unity 實現滑鼠控制角色移動和角色頭部的血條顯示

以夢為馬,不負韶華發表於2018-11-09

在很多專案中,都有這樣的場景就是滑鼠點選一個位置,滑鼠所控制的玩家就會移動到指定的位置處,還有就是在戰鬥過程中任務頭上血條的UI跟隨顯示,今天就講一下如何實現通過滑鼠控制人物移動和人物頭部血條的顯示。

一、首先是搭建簡易的3D場景

這裡使用Terrain地形元件,安裝官方資源之後,然後將對應的Environment匯入到專案中:

設定地形引數,可以刷一些樹木,草什麼的 ,自行編輯就行 ,這裡不做詳細解釋,場景如下圖:

 二、匯入人物模型,新增相機跟隨指令碼

這裡為了方便直接使用了官方提供的SmoothFollow指令碼,建立一個新的相機用於渲染模型,在這個相機上新增SmoothFollow,如下圖:

這裡Target就是目標物體也就是,當前的角色模型

三、實現滑鼠控制人物的移動:

首先建立一個指令碼PlayerControl,這裡主要就是通過射線檢測,點選到地面的位置,計算角色的轉向,然後沿著這個方向移動到指定位置 關於旋轉的角度主要是通過點乘獲得了目標位置對於玩家的朝向是背對著還是面對著,然後就是計算角度決定從那個方向旋轉到目標方向:

       if (Input.GetMouseButtonDown(0))
        {
            //獲取從主相機發出的一條射線
            Ray mRay = PlayerCamera.ScreenPointToRay(Input.mousePosition);
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))
            {
                if (mHit.collider.gameObject.name == "MyTerrain")
                {
                    mTargetPos = mHit.point;
                    Vector3 posTem = mHit.point - transform.position;
                    float dot = Vector3.Dot(posTem.normalized, transform.right);
                    float angle = Vector3.Angle(posTem.normalized, transform.forward);
                    transform.Rotate(new Vector3(0, dot > 0 ? angle : -angle, 0));
                }

                if (Time.realtimeSinceStartup - clickTimer < 0.2f)
                {
                    m_PlayerStastu = PlayerStastu.Run;
                    speed = 5;
                }
                else
                {
                    m_PlayerStastu = PlayerStastu.Walk;
                    speed = 2;
                }

                clickTimer = Time.realtimeSinceStartup;
            }
        }

上面還通過滑鼠的單機還是雙擊決定了角色的移動方式是行走還是奔跑,在這裡鎖定了角色的旋轉方向就是隻允許改變角色的y軸轉向,然後就是角色的移動和動畫的播放:

        if (m_PlayerStastu == PlayerStastu.Walk || m_PlayerStastu == PlayerStastu.Run)
        {
            PlayAnimation();
            //開始向指定方向移動
            transform.Translate(Vector3.forward * speed * Time.deltaTime);
            //計算和目標位置的距離         
            float targetDist = Vector3.Distance(mTargetPos, transform.position);
            //當兩者的距離小於0.1,停止移動
            if (targetDist <= 0.1f)
            {
                m_PlayerStastu = PlayerStastu.Idle;
                PlayAnimation();
            }
        }

四、實現血條的ui跟隨角色移動:

拼接一個血條的ui,這裡用的是ugui:

 這裡把ui的跟隨程式碼 放大了LateUpdate中實現,LateUpdate主要是在update後執行的,在這之後再去確定ui的位置,在一定程度上可以放置ui的抖動,具體區別可自行百度:

    void LateUpdate()
    {
        //處理ui 跟隨人物移動
        Vector3 screenPos = PlayerCamera.WorldToScreenPoint(transform.position);
        Vector3 uiPos = UICamera.ScreenToWorldPoint(screenPos);
        BloodUi.transform.localPosition = uiPos + new Vector3(0, 350, 0);
    }

最後就是關於動畫的播放,比較簡單:

     //播放動畫
    void PlayAnimation()
    {
        transform.GetComponent<Animation>().Play(m_PlayerStastu.ToString());
    }

下面是控制角色移動的完整指令碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    private Vector3 mTargetPos;  //滑鼠點選目標位置
    public Camera PlayerCamera;  //玩家相機
    public Camera UICamera; //ui相機
    public Transform BloodUi;  //血條ui
    private PlayerStastu m_PlayerStastu;  //當前玩家狀態
    private float clickTimer;  //記錄上次點選時間
    private float speed;

    private enum PlayerStastu
    {
        Idle,
        Walk,
        Run,
    }

    void Start()
    {
        m_PlayerStastu = PlayerStastu.Idle;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //獲取從主相機發出的一條射線
            Ray mRay = PlayerCamera.ScreenPointToRay(Input.mousePosition);
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))
            {
                if (mHit.collider.gameObject.name == "MyTerrain")
                {
                    mTargetPos = mHit.point;
                    Vector3 posTem = mHit.point - transform.position;
                    float dot = Vector3.Dot(posTem.normalized, transform.right);
                    float angle = Vector3.Angle(posTem.normalized, transform.forward);
                    transform.Rotate(new Vector3(0, dot > 0 ? angle : -angle, 0));
                }

                if (Time.realtimeSinceStartup - clickTimer < 0.2f)
                {
                    m_PlayerStastu = PlayerStastu.Run;
                    speed = 5;
                }
                else
                {
                    m_PlayerStastu = PlayerStastu.Walk;
                    speed = 2;
                }

                clickTimer = Time.realtimeSinceStartup;
            }
        }

        if (m_PlayerStastu == PlayerStastu.Walk || m_PlayerStastu == PlayerStastu.Run)
        {
            PlayAnimation();
            //開始向指定方向移動
            transform.Translate(Vector3.forward * speed * Time.deltaTime);
            //計算和目標位置的距離         
            float targetDist = Vector3.Distance(mTargetPos, transform.position);
            //當兩者的距離小於0.1,停止移動
            if (targetDist <= 0.1f)
            {
                m_PlayerStastu = PlayerStastu.Idle;
                PlayAnimation();
            }
        }
    }

    void LateUpdate()
    {
        //處理ui 跟隨人物移動
        Vector3 screenPos = PlayerCamera.WorldToScreenPoint(transform.position);
        Vector3 uiPos = UICamera.ScreenToWorldPoint(screenPos);
        BloodUi.transform.localPosition = uiPos + new Vector3(0, 350, 0);
    }

    //播放動畫
    void PlayAnimation()
    {
        transform.GetComponent<Animation>().Play(m_PlayerStastu.ToString());
    }
}

最後是實際執行效果:

想了解更多可以關注下方公眾號,或者新增QQ群:879354767

工程地址:

連結:https://pan.baidu.com/s/1IAZ0I2idBicWVvKeHQFQNg 
提取碼:x9g0 
 

 

相關文章