BoneLookAtPlayer.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using UdonSharp;
  2. using UnityEngine;
  3. using VRC.SDKBase;
  4. using VRC.Udon;
  5. using System;
  6. [DisallowMultipleComponent]
  7. [AddComponentMenu("Artyom Scripting System/Bone Look At Player")]
  8. public class BoneLookAtPlayer : UdonSharpBehaviour
  9. {
  10. public GameObject objectToRotate; // The object to rotate
  11. public float rotationSpeed = 90.0f; // Maximum rotation speed in degrees per second
  12. public Vector3 rotationOffset; // Rotation offset for each axis
  13. private Transform objectTransform;
  14. void Start()
  15. {
  16. if (objectToRotate != null)
  17. {
  18. objectTransform = objectToRotate.transform;
  19. }
  20. else
  21. {
  22. Debug.LogError("Object to rotate not assigned.");
  23. }
  24. }
  25. void Update()
  26. {
  27. VRCPlayerApi nearestPlayer = GetNearestPlayer(); // Method to get the nearest player
  28. if (nearestPlayer != null)
  29. {
  30. Vector3 playerHeadPosition = nearestPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).position;
  31. // Calculate the direction to look
  32. Vector3 directionToLook = playerHeadPosition - objectTransform.position;
  33. if (directionToLook != Vector3.zero)
  34. {
  35. Quaternion targetRotation = Quaternion.LookRotation(directionToLook);
  36. // Apply the rotation offset
  37. targetRotation *= Quaternion.Euler(rotationOffset);
  38. objectTransform.rotation = Quaternion.RotateTowards(objectTransform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
  39. }
  40. }
  41. }
  42. VRCPlayerApi GetNearestPlayer()
  43. {
  44. VRCPlayerApi nearestPlayer = null;
  45. float closestDistance = float.MaxValue;
  46. VRCPlayerApi[] players = new VRCPlayerApi[VRCPlayerApi.GetPlayerCount()];
  47. VRCPlayerApi.GetPlayers(players);
  48. Vector3 currentPosition = transform.position;
  49. foreach (VRCPlayerApi player in players)
  50. {
  51. if (player != null) // Allow local player for nearest search
  52. {
  53. float distance = Vector3.Distance(currentPosition, player.GetPosition());
  54. if (distance < closestDistance)
  55. {
  56. closestDistance = distance;
  57. nearestPlayer = player;
  58. }
  59. }
  60. }
  61. return nearestPlayer;
  62. }
  63. }