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


(2) 修改PlayerInput.cs和PlayerController.cs以实现飞行
添加以下属性
- [SerializeField]
- private float thrusterForce = 20f;
- [SerializeField]
- private ConfigurableJoint joint
在其Start方法中添加以下语句
joint = GetComponent();
在其Update方法中添加以下语句
- Vector3 force = Vector3.zero;
- if (Input.GetButton("Jump"))
- {
- force = Vector3.up * thrusterForce;
- joint.yDrive = new JointDrive
- {
- positionSpring = 0f,
- positionDamper = 0f,
- maximumForce = 0f,
- };
- }
- else
- {
- joint.yDrive = new JointDrive
- {
- positionSpring = 20f,
- positionDamper = 0f,
- maximumForce = 40f,
- };
- }
- playerControllor.Thrust(force);
添加以下属性
private Vector3 thrusterForce = Vector3.zero;//向上的推力
添加以下方法
- public void Thrust(Vector3 _thrusterForce)
- {
- thrusterForce = _thrusterForce;
- }
在其PerformMovement方法中添加以下语句
- if (thrusterForce != Vector3.zero)
- {
- rb.AddForce(thrusterForce);//作用Time.fixedDeltaTime秒:0.02秒
- thrusterForce = Vector3.zero;
- }
修改PlayerController.cs
添加以下属性
- private float cameraRoatationTotal = 0f;//累计转了多少度
- [SerializeField]
- private float cameraRotationLimit = 85f;
对其PerformRotation方法进行一下修改
- private void PerformRotation()
- {
- if (yRotation != Vector3.zero)
- {
- rb.transform.Rotate(yRotation);
- }
- if (xRotation != Vector3.zero)
- {
- cam.transform.Rotate(xRotation);
- cameraRoatationTotal += xRotation.x;
- cameraRoatationTotal = Mathf.Clamp(cameraRoatationTotal, -cameraRotationLimit, +cameraRotationLimit);
- cam.transform.localEulerAngles = new Vector3(cameraRoatationTotal, 0f, 0f);
- }
- }
(1) 创建并编写PlayerWeapon.cs,将其移动至Assets/Scripts/Player
- using System;
-
- [Serializable]
- public class PlayerWeapon
- {
- public string name = "M16";
- public int damage = 10;
- public float range = 100f;
- }
(2)在场景中创建空物体“GameManager”,创建并编写GameManager.cs并挂载至空物体“GameManager”


- using System;
- using UnityEngine;
-
- public class GameManager : MonoBehaviour
- {
- private static string info;
-
- public static void UpdateInfo(String _info)
- {
- info = _info;
- }
-
- private void OnGUI()
- {
- GUILayout.BeginArea(new Rect(200f,200f,200f,400f));
- GUILayout.BeginVertical();
- GUILayout.Label(info);
- GUILayout.EndVertical();
- GUILayout.EndArea();
- }
- }
(3)创建并编写PlayerShooting.cs并将其挂载至Player预制体,将其移至Assets/Scripts/Player
- using Unity.Netcode;
- using UnityEngine;
-
- public class PlayerShooting : NetworkBehaviour
- {
- [SerializeField]
- private PlayerWeapon weapon;
- [SerializeField]
- private LayerMask mask;
-
- private Camera cam;
-
- // Start is called before the first frame update
- void Start()
- {
- cam = GetComponentInChildren
(); - }
-
- // Update is called once per frame
- void Update()
- {
- if(Input.GetButton("Fire1"))
- {
- Shoot();
- }
- }
-
- private void Shoot()
- {
- RaycastHit hit;
- if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit,weapon.range,mask))
- {
- ShootServerRpc(hit.collider.name,weapon.damage);
- }
- }
-
- [ServerRpc]
- private void ShootServerRpc(string hittedName,int damage)
- {
- GameManager.UpdateInfo(transform.name+" hit "+hittedName);
- }
- }
(4) 修改NetworkUI.cs,实现“点击按钮后按钮消失”
- using Unity.Netcode;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class NetworkManagerUI : MonoBehaviour
- {
- [SerializeField]
- private Button hostBtn;
- [SerializeField]
- private Button serverBtn;
- [SerializeField]
- private Button clientBtn;
-
- // Start is called before the first frame update
- void Start()
- {
- hostBtn.onClick.AddListener(() =>
- {
- NetworkManager.Singleton.StartHost();
- DestroyAllButtons();
- });
- serverBtn.onClick.AddListener(() =>
- {
- NetworkManager.Singleton.StartServer();
- DestroyAllButtons();
- });
- clientBtn.onClick.AddListener(() =>
- {
- NetworkManager.Singleton.StartClient();
- DestroyAllButtons();
- });
- }
-
- private void DestroyAllButtons()
- {
- Destroy(hostBtn.gameObject);
- Destroy(serverBtn.gameObject);
- Destroy(clientBtn.gameObject);
- }
- }
(1)测试效果图

(按住空格起飞,朝向任意碰撞体按下鼠标左键,屏幕左上方出现命中提示)
(2)部分工程文件完整代码
- using UnityEngine;
-
- public class PlayerInput : MonoBehaviour
- {
- [SerializeField]
- private float speed = 5f;
- [SerializeField]
- private float thrusterForce = 20f;
- [SerializeField]
- private PlayerController playerControllor;
- [SerializeField]
- private float lookSensitivity = 8f;
- [SerializeField]
- private ConfigurableJoint joint;
-
- // Start is called before the first frame update
- void Start()
- {
- Cursor.lockState = CursorLockMode.Locked;
- joint = GetComponent
(); - }
-
- // Update is called once per frame
- void Update()
- {
- float xMov = Input.GetAxisRaw("Horizontal");
- float yMov = Input.GetAxisRaw("Vertical");
-
- Vector3 velocity = (transform.right * xMov + transform.forward * yMov).normalized*speed;
- playerControllor.Move(velocity);
-
- float xMouse = Input.GetAxisRaw("Mouse X");
- float yMouse = Input.GetAxisRaw("Mouse Y");
-
- Vector3 yRotation = new Vector3(0f, xMouse, 0f)*lookSensitivity;
- Vector3 xRotation = new Vector3(-yMouse, 0f, 0f)*lookSensitivity;
- playerControllor.Rotate(yRotation,xRotation);
-
- Vector3 force = Vector3.zero;
- if (Input.GetButton("Jump"))
- {
- force = Vector3.up * thrusterForce;
- joint.yDrive = new JointDrive
- {
- positionSpring = 0f,
- positionDamper = 0f,
- maximumForce = 0f,
- };
- }
- else
- {
- joint.yDrive = new JointDrive
- {
- positionSpring = 20f,
- positionDamper = 0f,
- maximumForce = 40f,
- };
- }
- playerControllor.Thrust(force);
- }
- }
- using UnityEngine;
-
- public class PlayerController : MonoBehaviour
- {
- [SerializeField]
- private Rigidbody rb;
- [SerializeField]
- private Camera cam;
-
- private Vector3 velocity = Vector3.zero;//速度:每秒钟移动的距离
- private Vector3 yRotation=Vector3.zero;//旋转角色
- private Vector3 xRotation = Vector3.zero;//旋转视角
-
- private float cameraRoatationTotal = 0f;//累计转了多少度
- [SerializeField]
- private float cameraRotationLimit = 85f;
-
- private Vector3 thrusterForce = Vector3.zero;//向上的推力
-
- public void Move(Vector3 _velocity)
- {
- velocity = _velocity;
- }
-
- public void Rotate(Vector3 _yRotation, Vector3 _xRotation)
- {
- yRotation = _yRotation;
- xRotation = _xRotation;
- }
-
- public void Thrust(Vector3 _thrusterForce)
- {
- thrusterForce = _thrusterForce;
- }
-
- private void PerformMovement()
- {
- if (velocity != Vector3.zero)
- {
- rb.MovePosition(rb.position+velocity*Time.fixedDeltaTime);
- }
-
- if (thrusterForce != Vector3.zero)
- {
- rb.AddForce(thrusterForce);//作用Time.fixedDeltaTime秒:0.02秒
- thrusterForce = Vector3.zero;
- }
- }
-
- private void PerformRotation()
- {
- if (yRotation != Vector3.zero)
- {
- rb.transform.Rotate(yRotation);
- }
- if (xRotation != Vector3.zero)
- {
- cam.transform.Rotate(xRotation);
- cameraRoatationTotal += xRotation.x;
- cameraRoatationTotal = Mathf.Clamp(cameraRoatationTotal, -cameraRotationLimit, +cameraRotationLimit);
- cam.transform.localEulerAngles = new Vector3(cameraRoatationTotal, 0f, 0f);
- }
- }
-
- private void FixedUpdate()
- {
- PerformMovement();
- PerformRotation();
- }
- }