2015年11月16日 星期一

FPS 強化版

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);
    }
}

---------------------------------------------------------

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



沒有留言:

張貼留言