PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值
文章目錄
- 🟥 效果展示
- 🟧 機器人運動
- 1?? 狀態機及狀態機控制
- 2?? 添加角色控制器
- 3?? 制作預制體
 
- 🟨 相機跟隨
- 🟩 攻擊系統
- 1?? 激光射線
- 2?? 碰撞器設置
- 3?? 激光控制
- 4?? 預制體Apply一下
 
- 🟦 生命值系統
🟥 效果展示
首先,將PUN設為離線模式,先來進行本地測試。等發布時,再取消勾選改為聯網模式。
為什么設置,可參考:傳送門
🟧 機器人運動
Robot Kyle 從Assets拖到層級面板,進行如下配置:
1?? 狀態機及狀態機控制
a、指定機器人狀態機:Kyle Robot
b、掛載如下代碼:
該代碼負責控制機器人運動,WAD運動,跑起來后右鍵跳躍。
using Photon.Pun; using UnityEngine;public class PlayerAnimatorManager : MonoBehaviourPun {#region Private Fields[SerializeField]float directionDampTime = 0.25f;Animator animator;#endregion#region Mono CallBacksvoid Start(){animator = GetComponent<Animator>();}void Update(){//教程參考:https://skode.blog.csdn.net/article/details/106356112if (PhotonNetwork.IsConnected == true && photonView.IsMine == false)return;AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);// 只有在我們跑步的時,按下右鍵才允許跳躍。if (stateInfo.IsName("Base Layer.Run") && Input.GetButtonDown("Fire2"))animator.SetTrigger("Jump");float h = Input.GetAxis("Horizontal");float v = Input.GetAxis("Vertical") < 0 ? 0 : Input.GetAxis("Vertical");animator.SetFloat("Speed", h * h + v * v);animator.SetFloat("Direction", h, directionDampTime, Time.deltaTime);}#endregion }2?? 添加角色控制器
為機器人添加 CharacterController,調整Center等,屬性如下:
3?? 制作預制體
創建 Resources 文件夾,將Robot Kyle拖到Resources制成預制體。
🟨 相機跟隨
為機器人添加如下腳本,勾選 FollwOnStart
該腳本的FollowOnStart,為離線模式,該功能是在離線模式下,讓攝像機自動找到人物跟隨。在發布時的聯網狀態下,需取消勾選,自己寫代碼判斷哪個人物是自己的,來跟隨。
你的Camera要為 MainCamera
using UnityEngine;// Camera work. Follow a target public class Skode_CameraWork : MonoBehaviour {#region Fields[Tooltip("在局部x-z平面到目標的距離")]public float distance = 7.0f;[Tooltip("我們希望相機高于目標的高度")]public float height = 3.0f;[Tooltip("相機高度的平滑時滯")]public float heightSmoothLag = 0.3f;[Tooltip("允許相機垂直于目標,例如,提供更多的景色和較少的地面")]public Vector3 centerOffset = Vector3.zero;[Tooltip("如果預制組件被光子網絡改變,則將此設置為false,并在需要時手動調用OnStartFollowing()")]public bool followOnStart = false;// cached transform of the targetTransform cameraTransform;// maintain a flag internally to reconnect if target is lost or camera is switchedbool isFollowing;// Represents the current velocity, this value is modified by SmoothDamp() every time you call it.float heightVelocity;// Represents the position we are trying to reach using SmoothDamp()float targetHeight = 100000.0f;#endregion#region Mono Callbacksvoid Start(){// Start following the target if wanted.if (followOnStart)OnStartFollowing();}void LateUpdate(){// The transform target may not destroy on level load,// so we need to cover corner cases where the Main Camera is different everytime we load a new scene, and reconnect when that happensif (cameraTransform == null && isFollowing)OnStartFollowing();// only follow is explicitly declaredif (isFollowing)Apply();}#endregion#region Public Methods/// <summary>/// Raises the start following event./// Use this when you don't know at the time of editing what to follow, typically instances managed by the photon network./// </summary>public void OnStartFollowing(){cameraTransform = Camera.main.transform;isFollowing = true;// we don't smooth anything, we go straight to the right camera shotCut();}#endregion#region Private Methods/// <summary>/// Follow the target smoothly/// </summary>void Apply(){Vector3 targetCenter = transform.position + centerOffset;// Calculate the current & target rotation anglesfloat originalTargetAngle = transform.eulerAngles.y;float currentAngle = cameraTransform.eulerAngles.y;// Adjust real target angle when camera is lockedfloat targetAngle = originalTargetAngle;currentAngle = targetAngle;targetHeight = targetCenter.y + height;// Damp the heightfloat currentHeight = cameraTransform.position.y;currentHeight = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, heightSmoothLag);// Convert the angle into a rotation, by which we then reposition the cameraQuaternion currentRotation = Quaternion.Euler(0, currentAngle, 0);// Set the position of the camera on the x-z plane to:// distance meters behind the targetcameraTransform.position = targetCenter;cameraTransform.position += currentRotation * Vector3.back * distance;// Set the height of the cameracameraTransform.position = new Vector3(cameraTransform.position.x, currentHeight, cameraTransform.position.z);// Always look at the targetSetUpRotation(targetCenter);}/// <summary>/// Directly position the camera to a the specified Target and center./// </summary>void Cut(){float oldHeightSmooth = heightSmoothLag;heightSmoothLag = 0.001f;Apply();heightSmoothLag = oldHeightSmooth;}/// <summary>/// Sets up the rotation of the camera to always be behind the target/// </summary>/// <param name="centerPos">Center position.</param>void SetUpRotation(Vector3 centerPos){Vector3 cameraPos = cameraTransform.position;Vector3 offsetToCenter = centerPos - cameraPos;// Generate base rotation only around y-axisQuaternion yRotation = Quaternion.LookRotation(new Vector3(offsetToCenter.x, 0, offsetToCenter.z));Vector3 relativeOffset = Vector3.forward * distance + Vector3.down * height;cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);}#endregion }🟩 攻擊系統
1?? 激光射線
在機器人Head下新建如圖所示兩個cube作為激光射線
2?? 碰撞器設置
只使用一個Collider就好,并作為觸發器,避免作為碰撞器將別人碰飛
- 將右眼激光的Collider移除,左眼Collider拉大包裹住兩個cube
- 勾選Collider的 isTrigger
- 將帶Collider射線的tag設為 beam
3?? 激光控制
機器人添加下方腳本,并將Beams賦值給它
實現:當按下鼠標左鍵,打開激光。松開左鍵,關閉激光。
在網絡中多人玩,還要考慮:
我按下了鼠標左鍵,那場景中的各個機器人,怎么判斷我是屬于誰,你按下鼠標左鍵我要不要執行程序?
if (photonView.IsMine),便實現了此功能。判斷這個機器人是不是我的。是的話,執行程序。
using UnityEngine; using Photon.Pun;public class PlayerManager : MonoBehaviour {#region Parameterspublic GameObject beams;//當用戶開火時,為Truebool IsFiring;#endregion#region Mono CallBacksvoid Awake(){beams.SetActive(false);}void Update(){if (PhotonNetwork.IsConnected == true && photonView.IsMine)ProcessInputs();if (IsFiring != beams.activeSelf)beams.SetActive(IsFiring);}#endregion#region Private Methodsvoid ProcessInputs(){//鼠標左鍵if (Input.GetButtonDown("Fire1"))IsFiring = true;if (Input.GetButtonUp("Fire1"))IsFiring = false;}#endregion }4?? 預制體Apply一下
🟦 生命值系統
目標:
當射線擊中時,扣0.1血,一直擊中,每秒0.1。
當生命值0時,離開房間。
1、GameManager改為單例
2、PlayerManager 更新如下:
using UnityEngine; using Photon.Pun;public class PlayerManager : MonoBehaviourPunCallbacks {#region Parameterspublic GameObject beams;public float Health = 1f;//當用戶開火時,為Truebool IsFiring;#endregion#region Mono CallBacksvoid Awake(){beams.SetActive(false);}void Update(){if (Health <= 0f)GameManager.ins.Skode_LeaveRoom();if (PhotonNetwork.IsConnected == true && photonView.IsMine)ProcessInputs();if (IsFiring != beams.activeSelf)beams.SetActive(IsFiring);}#endregion#region Private Methodsvoid ProcessInputs(){//鼠標左鍵if (Input.GetButtonDown("Fire1"))IsFiring = true;if (Input.GetButtonUp("Fire1"))IsFiring = false;}void OnTriggerEnter(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;Health -= 0.1f;}void OnTriggerStay(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;//乘以增量時間,防止因為幀率FPS不同,扣血不同(舉例:不乘,每幀執行一次扣血,卡的人比流暢的人扣血少)Health -= 0.1f * Time.deltaTime;}#endregion }
 大家還有什么問題,歡迎在下方留言!
 
 
 如果你有 技術的問題 或 項目開發 
都可以加下方聯系方式
和我聊一聊你的故事🧡
總結
以上是生活随笔為你收集整理的PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: panabit之PPPoE认证
- 下一篇: DENSE_RANK函数
