TankController.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using UnityEngine;
  2. using UnityEngine.AI;
  3. namespace Mirror.Examples.TanksCoop
  4. {
  5. public class TankController : NetworkBehaviour
  6. {
  7. [Header("Components")]
  8. public NavMeshAgent agent;
  9. public Animator animator;
  10. public Transform turret;
  11. [Header("Movement")]
  12. public float rotationSpeed = 100;
  13. [Header("Firing")]
  14. public KeyCode shootKey = KeyCode.Space;
  15. public GameObject projectilePrefab;
  16. public Transform projectileMount;
  17. void Update()
  18. {
  19. // take input from focused window only
  20. if (!Application.isFocused) return;
  21. // movement for local player
  22. if (isOwned)
  23. {
  24. // rotate
  25. float horizontal = Input.GetAxis("Horizontal");
  26. transform.Rotate(0, horizontal * rotationSpeed * Time.deltaTime, 0);
  27. // move
  28. float vertical = Input.GetAxis("Vertical");
  29. Vector3 forward = transform.TransformDirection(Vector3.forward);
  30. agent.velocity = forward * Mathf.Max(vertical, 0) * agent.speed;
  31. animator.SetBool("Moving", agent.velocity != Vector3.zero);
  32. // shoot
  33. if (Input.GetKeyDown(shootKey))
  34. {
  35. CmdFire();
  36. }
  37. RotateTurret();
  38. }
  39. }
  40. // this is called on the server
  41. [Command]
  42. void CmdFire()
  43. {
  44. GameObject projectile = Instantiate(projectilePrefab, projectileMount.position, projectileMount.rotation);
  45. NetworkServer.Spawn(projectile);
  46. RpcOnFire();
  47. }
  48. // this is called on the tank that fired for all observers
  49. [ClientRpc]
  50. void RpcOnFire()
  51. {
  52. animator.SetTrigger("Shoot");
  53. }
  54. void RotateTurret()
  55. {
  56. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  57. if (Physics.Raycast(ray, out RaycastHit hit, 100))
  58. {
  59. Debug.DrawLine(ray.origin, hit.point);
  60. Vector3 lookRotation = new Vector3(hit.point.x, turret.transform.position.y, hit.point.z);
  61. turret.transform.LookAt(lookRotation);
  62. }
  63. }
  64. public PlayerController playerController;
  65. public Transform seatPosition;
  66. [SyncVar(hook = nameof(OnOwnerChangedHook))]
  67. public NetworkIdentity objectOwner;
  68. void OnOwnerChangedHook(NetworkIdentity _old, NetworkIdentity _new)
  69. {
  70. //Debug.Log("OnOwnerChangedHook: " + objectOwner);
  71. // not ideal to adjust local players control status (or character model being hidden) via this hook, but it works for now
  72. if (objectOwner)
  73. {
  74. playerController = _new.GetComponent<PlayerController>();
  75. if (playerController) { playerController.canControlPlayer = false; }
  76. }
  77. else if(_old)
  78. {
  79. playerController = _old.GetComponent<PlayerController>();
  80. if (playerController) { playerController.canControlPlayer = true; }
  81. }
  82. }
  83. public override void OnStopServer()
  84. {
  85. // To prevent a bug that can be caused on client host, when scenes do not reset during play,
  86. // tank variables are set as "missing", which Unity does not count as null/empty.
  87. objectOwner = null;
  88. playerController = null;
  89. }
  90. }
  91. }