fps Script(c#):
using UnityEngine;
using System.Collections;
using UnityEditor;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class FPS : MonoBehaviour {
[MenuItem("PlayerMode/FPS")]
static void Fps() {
GameObject fps = new GameObject("FPS");
fps.transform.position = Vector3.zero;
// FPS add component
fps.AddComponent<FPS>();
GameObject cam = new GameObject("Camera");
cam.transform.parent = fps.transform;
// Camera add component
cam.AddComponent<Camera>();
cam.AddComponent<GUILayer>();
cam.AddComponent<FlareLayer>();
cam.AddComponent<AudioListener>();
cam.AddComponent<SimpleSmoothMouseLook>();
}
[SerializeField]
float speed = 10.0f, gravity = 10.0f, maxVelocityChange = 10f, jumpHeight = 2.0f;
[SerializeField]
bool canJump = true;
private bool grounded = false;
Rigidbody rigidbody;
CapsuleCollider playerCollider;
void Awake(){
rigidbody = GetComponent<Rigidbody>();
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
gameObject.AddComponent<FPS_Animation>();
}
void FixedUpdate() {
if (grounded) {
// Calculate how fast we should be moving
Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"),0, Input.GetAxis("Vertical"));
targetVelocity = transform.TransformDirection(targetVelocity);
// Apply a force that attempts to reach our target velocity
Vector3 velocity = rigidbody.velocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
//Jump
if (canJump && Input.GetButton("Jump"))
rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
}
rigidbody.AddForce(new Vector3(0,-gravity * rigidbody.mass, 0));
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
float CalculateJumpVerticalSpeed() {
return Mathf.Sqrt(2 * jumpHeight * gravity);
}
}
using System.Collections;
using UnityEditor;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class FPS : MonoBehaviour {
[MenuItem("PlayerMode/FPS")]
static void Fps() {
GameObject fps = new GameObject("FPS");
fps.transform.position = Vector3.zero;
// FPS add component
fps.AddComponent<FPS>();
GameObject cam = new GameObject("Camera");
cam.transform.parent = fps.transform;
// Camera add component
cam.AddComponent<Camera>();
cam.AddComponent<GUILayer>();
cam.AddComponent<FlareLayer>();
cam.AddComponent<AudioListener>();
cam.AddComponent<SimpleSmoothMouseLook>();
}
[SerializeField]
float speed = 10.0f, gravity = 10.0f, maxVelocityChange = 10f, jumpHeight = 2.0f;
[SerializeField]
bool canJump = true;
private bool grounded = false;
Rigidbody rigidbody;
CapsuleCollider playerCollider;
void Awake(){
rigidbody = GetComponent<Rigidbody>();
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
gameObject.AddComponent<FPS_Animation>();
}
void FixedUpdate() {
if (grounded) {
// Calculate how fast we should be moving
Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"),0, Input.GetAxis("Vertical"));
targetVelocity = transform.TransformDirection(targetVelocity);
// Apply a force that attempts to reach our target velocity
Vector3 velocity = rigidbody.velocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
//Jump
if (canJump && Input.GetButton("Jump"))
rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
}
rigidbody.AddForce(new Vector3(0,-gravity * rigidbody.mass, 0));
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
float CalculateJumpVerticalSpeed() {
return Mathf.Sqrt(2 * jumpHeight * gravity);
}
}
---------------------------------------------------------
SimpleSmoothMouseLook (c#):
using UnityEngine;
using System.Collections;
[AddComponentMenu("Camera/Simple Smooth Mouse Look ")]
public class SimpleSmoothMouseLook : MonoBehaviour {
Vector2 _mouseAbsolute;
Vector2 _smoothMouse;
public Vector2 clampInDegrees = new Vector2(360, 180);
public bool lockCursor;
public Vector2 sensitivity = new Vector2(2, 2);
public Vector2 smoothing = new Vector2(3, 3);
public Vector2 targetDirection;
public Vector2 targetCharacterDirection;
// Assign this if there's a parent object controlling motion, such as a Character Controller.
// Yaw rotation will affect this object instead of the camera if set.
public GameObject characterBody;
void Start()
{
// Set target direction to the camera's initial orientation.
targetDirection = transform.localRotation.eulerAngles;
// Set target direction for the character body to its inital state.
if (characterBody) targetCharacterDirection = characterBody.transform.localRotation.eulerAngles;
}
void Update()
{
// Ensure the cursor is always locked when set
Screen.lockCursor = lockCursor;
// Allow the script to clamp based on a desired target value.
var targetOrientation = Quaternion.Euler(targetDirection);
var targetCharacterOrientation = Quaternion.Euler(targetCharacterDirection);
// Get raw mouse input for a cleaner reading on more sensitive mice.
var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
// Scale input against the sensitivity setting and multiply that against the smoothing value.
mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));
// Interpolate mouse movement over time to apply smoothing delta.
_smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
_smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);
// Find the absolute mouse movement value from point zero.
_mouseAbsolute += _smoothMouse;
// Clamp and apply the local x value first, so as not to be affected by world transforms.
if (clampInDegrees.x < 360)
_mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);
var xRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right);
transform.localRotation = xRotation;
// Then clamp and apply the global y value.
if (clampInDegrees.y < 360)
_mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);
transform.localRotation *= targetOrientation;
// If there's a character body that acts as a parent to the camera
if (characterBody)
{
var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, characterBody.transform.up);
characterBody.transform.localRotation = yRotation;
characterBody.transform.localRotation *= targetCharacterOrientation;
}
else
{
var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(Vector3.up));
transform.localRotation *= yRotation;
}
}
}
參考 : http://forum.unity3d.com/threads/a-free-simple-smooth-mouselook.73117/
-----------------------------------
版面設定 :
Collider Setting (碰撞器設定):
1. Capsule Collider - Center : 設定碰撞器位置
2. Capsule Collider - Radius : 設定碰撞器寬度
3. Capsule Collider - Height : 設定碰撞器高度
Camera Setting (攝影機設定)
SimpleSmoothMouseLook - Lock Cousor : 設定視窗是否出現鼠標
SimpleSmoothMouseLook - CharacterBody : 放置人物模型
-------------------------------------------------
FPS (非插件,Animation)
不知道是怎麼回事,用插件寫法要寫 Animator Controller 都沒動靜 冏......天殺的
以下程式碼是非插件,包含動畫程式。
fps :
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(FPSAnimation))]
public class FPS : MonoBehaviour {
[SerializeField]
float gravity = 10.0f, maxVelocityChange = 50f, jumpHeight = 2.0f;
[SerializeField]
bool canJump = true;
private bool grounded = false;
Rigidbody rigidbody;
CapsuleCollider characterController;
void Awake(){
rigidbody = GetComponent<Rigidbody>();
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
}
void FixedUpdate() {
if (grounded) {
// Calculate how fast we should be moving
Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"),0, Input.GetAxis("Vertical"));
targetVelocity = transform.TransformDirection(targetVelocity);
// Apply a force that attempts to reach our target velocity
Vector3 velocity = rigidbody.velocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
//Jump
if (canJump && Input.GetButton("Jump"))
rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
}
rigidbody.AddForce(new Vector3(0,-gravity * rigidbody.mass, 0));
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
float CalculateJumpVerticalSpeed() {
return Mathf.Sqrt(2 * jumpHeight * gravity);
}
}
-----------------------------------------
FPSAnimation(c#):
using UnityEngine;
using System.Collections;
public class FPSAnimation : MonoBehaviour {
[SerializeField]
Animator animator;
bool jump;
void Update() {
float _vertical = Input.GetAxis("Vertical");
float _horizontal = Input.GetAxis("Horizontal");
bool value = (_vertical != 0) ? true : false;
// Run
animator.SetBool("RunSw", value);
animator.SetFloat("Run", _vertical);
if (_horizontal < 0) {
animator.SetFloat("RunPoint", _horizontal);
animator.SetBool("Jump",jump);
}else if (_horizontal > 0) {
animator.SetFloat("RunPoint", _horizontal);
animator.SetBool("Jump", jump);
}
if (_horizontal.Equals(0)) {
animator.SetFloat("RunPoint", 0);
}
//Walk
if (_horizontal < 0){
animator.SetFloat("WalkPoint", _horizontal);
}else if (_horizontal > 0){
animator.SetFloat("WalkPoint", _horizontal);
}
if (_horizontal.Equals(0)){
animator.SetFloat("WalkPoint", 0);
}
//WalkB
bool walkB = (_vertical < 0) ? true : false;
animator.SetBool("WalkPointB", walkB);
// Rotation
bool turnSw = (_horizontal != 0) ? false : true;
animator.SetBool("TurnSw", turnSw);
if (_horizontal < 0){
animator.SetFloat("TurnPoint", _horizontal);
}else if (_horizontal > 0) {
animator.SetFloat("TurnPoint", _horizontal);
}
//jump
jump = (Input.GetButton("Jump")) ? true : false;
animator.SetBool("Jump", jump);
}
}
觀看結果影片
DownFile : http://pan.baidu.com/s/1hqjR4lm
※ 專案 修改部分
1. Jump 動畫 記得要改成Loop
2. 以圖顯示修改部分
---------------------------------------------------
如果搭配以下動畫FPS 程式請修改
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(CharectersAnimation))]
public class FPS : MonoBehaviour {
[SerializeField]
float gravity = 10.0f, maxVelocityChange = 50f, jumpHeight = 2.0f;
[SerializeField]
bool canJump = true;
private bool grounded = false;
Rigidbody rigidbody;
CapsuleCollider characterController;
void Awake(){
rigidbody = GetComponent<Rigidbody>();
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
characterController = GetComponent<CapsuleCollider>();
}
void FixedUpdate() {
if (grounded) {
// Calculate how fast we should be moving
Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
targetVelocity = transform.TransformDirection(targetVelocity);
// Apply a force that attempts to reach our target velocity
Vector3 velocity = rigidbody.velocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
bool jumpsw = (CharectersAnimation._idleOver != false) ? false : true;
canJump = jumpsw;
Debug.Log(jumpsw);
//Jump
if (canJump & Input.GetButton("Jump"))
rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
}
rigidbody.AddForce(new Vector3(0,-gravity * rigidbody.mass, 0));
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
float CalculateJumpVerticalSpeed() {
return Mathf.Sqrt(2 * jumpHeight * gravity);
}
}
動畫較完整寫法:
CharectersAnimation (c#) :
using UnityEngine;
using System.Collections;
public class CharectersAnimation : MonoBehaviour {
[SerializeField]
Animator animator;
public static int runtimdeDate, idletimdeDate;
private string[] IdleName = new string[] { "WAIT01", "WAIT02", "WAIT03", "WAIT04" }; //Idle Name
private float _vertical, _horizontal;
public static bool _idleOver;
void Start() {
InvokeRepeating("Idle_Time",1f, 1f); // animation time Date
}
void Idle_Time() {
idletimdeDate += 1; // idletimeDate
_idleOver = (_vertical.Equals(0) & _horizontal.Equals(0) & animator.GetBool("Run").Equals(false)) ? true : false; // No direction key and jump value true else false
animator.SetBool("IdleOver", _idleOver);
if (_vertical.Equals(0) & _horizontal.Equals(0))
{
if (idletimdeDate.Equals(10)) // idle Animation
{
int sum = Random.Range(0, 3);
string str = IdleName[sum];
animator.Play(str);
}
}
if (animator.GetBool("Run").Equals(true)) // run time Date
runtimdeDate += 1;
else runtimdeDate = 0;
bool _tired = (runtimdeDate.Equals(5)) ? true : false; // Tired animation
animator.SetBool("Tired", _tired);
if (runtimdeDate > 5) { // run limit time date
runtimdeDate = 0;
}
if (idletimdeDate > 10) { // idle limit time date
idletimdeDate = 0;
}
}
// Update is called once per frame
void Update () {
_vertical = Input.GetAxis("Vertical");
_horizontal = Input.GetAxis("Horizontal");
float _walk = (_vertical < 0) ? _vertical : _vertical; // walk to return and wait control
animator.SetFloat("Walk", _walk);
bool _walkH = (_horizontal != 0) ? true : false; // direction key control
animator.SetBool("WalkH", _walkH);
float _walkPoint = (_horizontal < 0) ? _horizontal : _horizontal; // direction key control
animator.SetFloat("WalkPoint", _walkPoint);
bool _run = (Input.GetKey(KeyCode.LeftShift)) ? true : false; // run control
animator.SetBool("Run", _run);
float _runPoint = (_horizontal < 0)? _horizontal : _horizontal; // run direction control
animator.SetFloat("RunPoint", _runPoint);
bool _jump = (Input.GetButton("Jump")) ? true : false ; // jump control
animator.SetBool("Jump",_jump);
bool _raise = (Input.GetMouseButton(0)) ? true : false; // raise control
animator.SetBool("Raise ", _raise);
}
}
download file : http://pan.baidu.com/s/1qWINxLU
沒有留言:
張貼留言