• 三、飞行和射击


    目录

    1.飞行的实现

    2.限制玩家视角

    3.射击的实现

    4.附录


    1.飞行的实现

    (1)在Player预制体上挂载Configuration Joint组件,并修改其Y Drive属性

    (2) 修改PlayerInput.cs和PlayerController.cs以实现飞行

    • PlayerInput.cs

    添加以下属性 

    1. [SerializeField]
    2. private float thrusterForce = 20f;
    3. [SerializeField]
    4. private ConfigurableJoint joint

     在其Start方法中添加以下语句

    joint = GetComponent();

    在其Update方法中添加以下语句 

    1. Vector3 force = Vector3.zero;
    2. if (Input.GetButton("Jump"))
    3. {
    4. force = Vector3.up * thrusterForce;
    5. joint.yDrive = new JointDrive
    6. {
    7. positionSpring = 0f,
    8. positionDamper = 0f,
    9. maximumForce = 0f,
    10. };
    11. }
    12. else
    13. {
    14. joint.yDrive = new JointDrive
    15. {
    16. positionSpring = 20f,
    17. positionDamper = 0f,
    18. maximumForce = 40f,
    19. };
    20. }
    21. playerControllor.Thrust(force);
    • PlayerController.cs

    添加以下属性 

    private Vector3 thrusterForce = Vector3.zero;//向上的推力

     添加以下方法

    1. public void Thrust(Vector3 _thrusterForce)
    2. {
    3. thrusterForce = _thrusterForce;
    4. }

     在其PerformMovement方法中添加以下语句

    1. if (thrusterForce != Vector3.zero)
    2. {
    3. rb.AddForce(thrusterForce);//作用Time.fixedDeltaTime秒:0.02秒
    4. thrusterForce = Vector3.zero;
    5. }

    2.限制玩家视角

     修改PlayerController.cs

    添加以下属性

    1. private float cameraRoatationTotal = 0f;//累计转了多少度
    2. [SerializeField]
    3. private float cameraRotationLimit = 85f;

    对其PerformRotation方法进行一下修改

    1. private void PerformRotation()
    2. {
    3. if (yRotation != Vector3.zero)
    4. {
    5. rb.transform.Rotate(yRotation);
    6. }
    7. if (xRotation != Vector3.zero)
    8. {
    9. cam.transform.Rotate(xRotation);
    10. cameraRoatationTotal += xRotation.x;
    11. cameraRoatationTotal = Mathf.Clamp(cameraRoatationTotal, -cameraRotationLimit, +cameraRotationLimit);
    12. cam.transform.localEulerAngles = new Vector3(cameraRoatationTotal, 0f, 0f);
    13. }
    14. }

    3.射击的实现

    (1) 创建并编写PlayerWeapon.cs,将其移动至Assets/Scripts/Player

    1. using System;
    2. [Serializable]
    3. public class PlayerWeapon
    4. {
    5. public string name = "M16";
    6. public int damage = 10;
    7. public float range = 100f;
    8. }

    (2)在场景中创建空物体“GameManager”,创建并编写GameManager.cs并挂载至空物体“GameManager”

    • GameManager.cs
    1. using System;
    2. using UnityEngine;
    3. public class GameManager : MonoBehaviour
    4. {
    5. private static string info;
    6. public static void UpdateInfo(String _info)
    7. {
    8. info = _info;
    9. }
    10. private void OnGUI()
    11. {
    12. GUILayout.BeginArea(new Rect(200f,200f,200f,400f));
    13. GUILayout.BeginVertical();
    14. GUILayout.Label(info);
    15. GUILayout.EndVertical();
    16. GUILayout.EndArea();
    17. }
    18. }

    (3)创建并编写PlayerShooting.cs并将其挂载至Player预制体,将其移至Assets/Scripts/Player

    1. using Unity.Netcode;
    2. using UnityEngine;
    3. public class PlayerShooting : NetworkBehaviour
    4. {
    5. [SerializeField]
    6. private PlayerWeapon weapon;
    7. [SerializeField]
    8. private LayerMask mask;
    9. private Camera cam;
    10. // Start is called before the first frame update
    11. void Start()
    12. {
    13. cam = GetComponentInChildren();
    14. }
    15. // Update is called once per frame
    16. void Update()
    17. {
    18. if(Input.GetButton("Fire1"))
    19. {
    20. Shoot();
    21. }
    22. }
    23. private void Shoot()
    24. {
    25. RaycastHit hit;
    26. if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit,weapon.range,mask))
    27. {
    28. ShootServerRpc(hit.collider.name,weapon.damage);
    29. }
    30. }
    31. [ServerRpc]
    32. private void ShootServerRpc(string hittedName,int damage)
    33. {
    34. GameManager.UpdateInfo(transform.name+" hit "+hittedName);
    35. }
    36. }

    (4) 修改NetworkUI.cs,实现“点击按钮后按钮消失”

    1. using Unity.Netcode;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. public class NetworkManagerUI : MonoBehaviour
    5. {
    6. [SerializeField]
    7. private Button hostBtn;
    8. [SerializeField]
    9. private Button serverBtn;
    10. [SerializeField]
    11. private Button clientBtn;
    12. // Start is called before the first frame update
    13. void Start()
    14. {
    15. hostBtn.onClick.AddListener(() =>
    16. {
    17. NetworkManager.Singleton.StartHost();
    18. DestroyAllButtons();
    19. });
    20. serverBtn.onClick.AddListener(() =>
    21. {
    22. NetworkManager.Singleton.StartServer();
    23. DestroyAllButtons();
    24. });
    25. clientBtn.onClick.AddListener(() =>
    26. {
    27. NetworkManager.Singleton.StartClient();
    28. DestroyAllButtons();
    29. });
    30. }
    31. private void DestroyAllButtons()
    32. {
    33. Destroy(hostBtn.gameObject);
    34. Destroy(serverBtn.gameObject);
    35. Destroy(clientBtn.gameObject);
    36. }
    37. }

    4.附录 

    (1)测试效果图

    (按住空格起飞,朝向任意碰撞体按下鼠标左键,屏幕左上方出现命中提示) 

    (2)部分工程文件完整代码

    • PlayerInput.cs
    1. using UnityEngine;
    2. public class PlayerInput : MonoBehaviour
    3. {
    4. [SerializeField]
    5. private float speed = 5f;
    6. [SerializeField]
    7. private float thrusterForce = 20f;
    8. [SerializeField]
    9. private PlayerController playerControllor;
    10. [SerializeField]
    11. private float lookSensitivity = 8f;
    12. [SerializeField]
    13. private ConfigurableJoint joint;
    14. // Start is called before the first frame update
    15. void Start()
    16. {
    17. Cursor.lockState = CursorLockMode.Locked;
    18. joint = GetComponent();
    19. }
    20. // Update is called once per frame
    21. void Update()
    22. {
    23. float xMov = Input.GetAxisRaw("Horizontal");
    24. float yMov = Input.GetAxisRaw("Vertical");
    25. Vector3 velocity = (transform.right * xMov + transform.forward * yMov).normalized*speed;
    26. playerControllor.Move(velocity);
    27. float xMouse = Input.GetAxisRaw("Mouse X");
    28. float yMouse = Input.GetAxisRaw("Mouse Y");
    29. Vector3 yRotation = new Vector3(0f, xMouse, 0f)*lookSensitivity;
    30. Vector3 xRotation = new Vector3(-yMouse, 0f, 0f)*lookSensitivity;
    31. playerControllor.Rotate(yRotation,xRotation);
    32. Vector3 force = Vector3.zero;
    33. if (Input.GetButton("Jump"))
    34. {
    35. force = Vector3.up * thrusterForce;
    36. joint.yDrive = new JointDrive
    37. {
    38. positionSpring = 0f,
    39. positionDamper = 0f,
    40. maximumForce = 0f,
    41. };
    42. }
    43. else
    44. {
    45. joint.yDrive = new JointDrive
    46. {
    47. positionSpring = 20f,
    48. positionDamper = 0f,
    49. maximumForce = 40f,
    50. };
    51. }
    52. playerControllor.Thrust(force);
    53. }
    54. }
    • PlayerController.cs 
    1. using UnityEngine;
    2. public class PlayerController : MonoBehaviour
    3. {
    4. [SerializeField]
    5. private Rigidbody rb;
    6. [SerializeField]
    7. private Camera cam;
    8. private Vector3 velocity = Vector3.zero;//速度:每秒钟移动的距离
    9. private Vector3 yRotation=Vector3.zero;//旋转角色
    10. private Vector3 xRotation = Vector3.zero;//旋转视角
    11. private float cameraRoatationTotal = 0f;//累计转了多少度
    12. [SerializeField]
    13. private float cameraRotationLimit = 85f;
    14. private Vector3 thrusterForce = Vector3.zero;//向上的推力
    15. public void Move(Vector3 _velocity)
    16. {
    17. velocity = _velocity;
    18. }
    19. public void Rotate(Vector3 _yRotation, Vector3 _xRotation)
    20. {
    21. yRotation = _yRotation;
    22. xRotation = _xRotation;
    23. }
    24. public void Thrust(Vector3 _thrusterForce)
    25. {
    26. thrusterForce = _thrusterForce;
    27. }
    28. private void PerformMovement()
    29. {
    30. if (velocity != Vector3.zero)
    31. {
    32. rb.MovePosition(rb.position+velocity*Time.fixedDeltaTime);
    33. }
    34. if (thrusterForce != Vector3.zero)
    35. {
    36. rb.AddForce(thrusterForce);//作用Time.fixedDeltaTime秒:0.02秒
    37. thrusterForce = Vector3.zero;
    38. }
    39. }
    40. private void PerformRotation()
    41. {
    42. if (yRotation != Vector3.zero)
    43. {
    44. rb.transform.Rotate(yRotation);
    45. }
    46. if (xRotation != Vector3.zero)
    47. {
    48. cam.transform.Rotate(xRotation);
    49. cameraRoatationTotal += xRotation.x;
    50. cameraRoatationTotal = Mathf.Clamp(cameraRoatationTotal, -cameraRotationLimit, +cameraRotationLimit);
    51. cam.transform.localEulerAngles = new Vector3(cameraRoatationTotal, 0f, 0f);
    52. }
    53. }
    54. private void FixedUpdate()
    55. {
    56. PerformMovement();
    57. PerformRotation();
    58. }
    59. }
  • 相关阅读:
    亚马逊一分钟1000+的僵尸链接获取只需三步
    springBoot
    React复习笔记
    Spring IOC/DI和MVC及若依对应介绍
    【Linux】进程地址空间
    全景应用程序监控
    CLR via C#-托管堆和垃圾回收
    Linux 进程控制
    在线招聘江湖:老、中、新三代平台对垒
    log4j设置日志的时区
  • 原文地址:https://blog.csdn.net/qq_53401568/article/details/133470756