http://clonefactor.com/20171230_DaughterSandbox_Data/
Demo record :
在物理測試中,unity3D人物的ragdoll 設定其實很簡陋, 看來要做一個自然的死屍也有一定的功夫要做.
也順道分享一個簡單的攝像頭寫法, 因為測試時希望快速進入 Game Mode 而又懶惰的關係.
所以預先做好了跟 Unity3D 有 80% 相似的鏡頭動作 Script,
需要時直接放到 Camera 元件上即可. 平台是 PC + Editor 限定.
又沒有達到可以發售的程度所以直接在這邊公開分享算了.
有用處的隨便, 有建議的也歡迎提點一下 (e.g. 手機支持等等….)
Known bugs:
好像在 WebGL 環境需要 Right + 任何其他鍵才能夠成功觸發. 原因應該是 HTML 的 context menu. 不過那是系統的 bug.
ObserverMovement.cs
using UnityEngine;
using UnityEngine.Networking;
namespace Kit
{
	public class ObserverMovement : MonoBehaviour
	{
		[Header("Common")]
		public float m_Speed = 0.5f;
		public float m_HighSpeed = 2f;
		[Header("Optional")]
		public NetworkIdentity m_NetworkIdentity;
		public Camera m_Camera;
		private float m_CurrentSpeed = 0f;
		private bool m_ToggleSpeed = false;
		private Vector3 m_LocalTranslate = Vector3.zero;
		private Vector2 m_LocalLook = Vector2.zero;
		void OnValidate()
		{
			if (m_NetworkIdentity == null)
			{
				m_NetworkIdentity = GetComponent<NetworkIdentity>();
			}
			if (m_NetworkIdentity != null)
			{
				if (m_Camera == null)
					m_Camera = GetComponentInChildren<Camera>(true);
			}
		}
		
		void InputUpdate()
		{
			// Mouse look
			if ((Input.GetMouseButton(1) || Input.GetMouseButton(2)) &&
				Cursor.lockState != CursorLockMode.Locked)
			{
				Cursor.lockState = CursorLockMode.Locked;
			}
			if ((Input.GetMouseButtonUp(1) || Input.GetMouseButtonUp(2)) &&
				Cursor.lockState != CursorLockMode.None)
			{
				Cursor.lockState = CursorLockMode.None;
			}
			if (Cursor.lockState == CursorLockMode.Locked)
			{
				m_LocalLook.x = -Input.GetAxis("Mouse Y");
				m_LocalLook.y = Input.GetAxis("Mouse X");
			}
			// Speed
			if (!m_ToggleSpeed &&
				Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift))
			{
				m_ToggleSpeed = true;
			}
			else if (m_ToggleSpeed &&
				(Input.GetKeyUp(KeyCode.LeftShift) || Input.GetKeyUp(KeyCode.RightShift)) &&
				!(Input.GetKey(KeyCode.LeftShift) && Input.GetKey(KeyCode.RightShift)))
			{
				m_ToggleSpeed = false;
			}
			m_CurrentSpeed = (m_ToggleSpeed) ? m_HighSpeed : m_Speed;
			// Movement
			if (Input.GetAxis("Vertical") != 0)
			{
				m_LocalTranslate += transform.forward * m_CurrentSpeed * Input.GetAxis("Vertical");
			}
			if (Input.GetAxis("Horizontal") != 0)
			{
				m_LocalTranslate += transform.right * m_CurrentSpeed * Input.GetAxis("Horizontal");
			}
			if (Input.GetKey(KeyCode.E) && !Input.GetKey(KeyCode.Q))
			{
				m_LocalTranslate += transform.up * m_CurrentSpeed * 0.5f;
			}
			if (Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.E))
			{
				m_LocalTranslate += -transform.up * m_CurrentSpeed * 0.5f;
			}
		}
		void Update()
		{
			if (m_NetworkIdentity != null && !m_NetworkIdentity.isLocalPlayer)
			{
				NetworkNPCUpdate();
			}
			else
			{
				LocalPlayerUpdate();
			}
		}
		void NetworkNPCUpdate()
		{
			if (m_Camera != null)
				m_Camera.enabled = false;
		}
		void LocalPlayerUpdate()
		{
			InputUpdate();
			// Apply
			transform.Translate(m_LocalTranslate, Space.World);
			if (Cursor.lockState == CursorLockMode.Locked)
			{
				transform.Rotate(Vector3.right, m_LocalLook.x, Space.Self);
				transform.Rotate(Vector3.up, m_LocalLook.y, Space.World);
			}
			// Reset
			m_LocalTranslate = Vector3.zero;
			m_LocalLook = Vector2.zero;
		}
	}
}

