using UdonSharp; using UnityEngine; using VRC.SDKBase; using VRC.Udon; namespace VRCBoard.Components { public class VRCBoardOverheadIcons : VRCBoardBaseComponent { public Texture2D[] icons; public string[] requiredTags; public Transform follower; private bool ArrayContains(string[] array, string value) { foreach (string s in array) { if (s == value) return true; } return false; } private VRCPlayerApi _owner; protected override void OnRegister() {} protected override void OnInitialize() { UpdateIcon(); } protected override void OnSupporterDataUpdate() { UpdateIcon(); } protected override void OnImageDataUpdate() {} protected override void OnImageLoaded() {} private Texture2D _iconForPlayer; private bool _active = false; private readonly Vector3 _iconOffset = new Vector3(0, 1.5f, 0); void UpdateIcon() { Debug.Log("Updating icon"); _active = (_owner != null && _owner.IsValid()); Debug.Log("Owner is valid: " + _active); if (!_active) return; string[] tags = manager.GetPlayerTags(_owner.displayName); for (int i = 0; i < requiredTags.Length; i++) { if (ArrayContains(tags, requiredTags[i])) { _iconForPlayer = icons[i]; Debug.Log("Found tag " + requiredTags[i] + " for player " + _owner.displayName); return; } } } void Start() { _owner = Networking.GetOwner(gameObject); } void Update() { //Debug.Log(_active); if (_owner == null) return; Vector3 headPos = _owner.GetBonePosition(HumanBodyBones.Head); Vector3 iconPos = headPos + _iconOffset; follower.position = iconPos; } } }