Unity 2d 鼠標左鍵跟隨腳本


前言

經過三個小時研究,終於實現Unity 2d的鼠標跟隨腳本

Unity2d不自帶AI導航尋路,故不能使用3d的鼠標跟隨腳本

目錄

功能效果

自動導航中人物動畫的修正

一個關鍵的狀態標記變量 autoNavi

操作方式的區分

autoNavi狀態標記變量解決了Follow單腳本鼠標導航的三個bug

           一、到達目的地之后,仍處於自動導航狀態,不能用鍵盤操控離開標記點,

                  且停止后人物方向與位移方向不匹配

           二、自動導航中無法用鍵盤改變運動方向

           三、自動導航過程中,人物動畫的顯示與運動方向不匹配

完整腳本,掛載即可使用

功能效果

只要掛載到一個對象上,即可實現鼠標左鍵跟隨

只需要掛載一個腳本,無需任何插件,即可實現點哪走哪!!

當玩家單擊鼠標左鍵時(某些游戲會生成一個箭頭動畫,指向點擊處)人物自動移動到鼠標點擊處。

自動導航中人物動畫的修正

如果不進行修正,人物將始終處於一個方向,不可改變

為了人物動畫的正常顯示,還需要獲取人物移動的方向向量。

分多種情況,把向量的x,y值傳給動畫狀態集。

一個關鍵的狀態標記變量 autoNavi

    //是否處於自動導航狀態
    public static bool autonavi = false;

設置為static,便於UI腳本取消按鍵時的不必要移動

操作方式的區分

我們要實現的移動

不是"保持鼠標左鍵按下移動"

而是"單擊一次之后,除非被打斷,否則要持續移動至目的地"

autoNavi狀態標記變量解決了Follow單腳本鼠標導航的三個bug

一、到達目的地之后,仍處於自動導航狀態,不能用鍵盤操控離開標記點,且停止后人物方向與位移方向不匹配

如果到達、則停止這次自動導航,取消標記

if (gameObject.transform.position.x== hitPoint.x && gameObject.transform.position.y== hitPoint.y)
		{
			clicked = false;
			//默認停止顯示正面或反面
			anim.SetFloat("move X", 0);
			anim.SetFloat("move Y", lookDirection.y);
			anim.SetFloat("runspeed", 0);
			Debug.Log(lookDirection);
		}

二、自動導航中無法用鍵盤改變運動方向

如果在自動前往目的地時,按下了方向鍵,撤銷這次自動導航,取消標記

//如果在自動前往目的地時,按下了方向鍵,撤銷這次自動導航,取消標記
		if(Input.GetAxisRaw("Horizontal")!=0||Input.GetAxisRaw("Vertical")!=0)
		{
			clicked = false;
		}

三、自動導航過程中,人物動畫的顯示與運動方向不匹配

如果這次自動導航未被打斷,並且未結束,標記仍然存在,則為運動中的動畫狀態集賦值,人物的方向在運動結束后回到運動前的朝向

		//如果這次自動導航未被打斷,並且未結束,標記仍然存在,則為運動中的動畫狀態集賦值,結束后回到運動前的朝向
		if (clicked == true && moveDirection.x != 0 && moveDirection.y != 0)
		{
			//為動畫集賦值
			//狀態集的切換由運動矢量決定
			anim.SetFloat("move X", lookDirection.x);
			anim.SetFloat("move Y", lookDirection.y);
			anim.SetFloat("runspeed", moveDirection.magnitude);
			Debug.Log(lookDirection);
		}

完整腳本,掛載即可使用

using UnityEngine;
using System.Collections;

public class Follow : MonoBehaviour
{
	//目的地,射線與平面的交點
	private Vector2 hitPoint;
	//自動導航速度
	public float speed = 3;
	//是否點擊
	private bool clicked = false;

	//定義動畫
	Animator anim;

	//初始屏幕看
	Vector2 lookDirection = new Vector2(0, -1);

	// Use this for initialization
	void Start()
	{
		//獲取動畫組件
		anim = GetComponent<Animator>();
	}

	// Update is called once per frame
	void Update()
	{
		//方向向量
		Vector2 curposition = new Vector2(gameObject.transform.position.x, gameObject.transform.position.y);
		Vector2 moveDirection = hitPoint - curposition;
		if (moveDirection.x != 0 || moveDirection.y != 0)
		{
			lookDirection = moveDirection;
		}

		//按下鼠標左鍵
		if (Input.GetMouseButtonDown(0))
		{
			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit2D raycast = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
			if (raycast.collider != null)
			{
				hitPoint = new Vector2(raycast.point.x, raycast.point.y);
				Debug.Log(raycast.point.x+"/"+ raycast.point.y);
				Debug.Log("clicked object name is ---->" + raycast.collider.gameObject);
			}
			clicked = true;
		}
            //標記了才會自動導航
		if (clicked) gameObject.transform.position = Vector2.MoveTowards(gameObject.transform.position, hitPoint, Time.deltaTime * speed);
		//如果到達、則停止這次自動導航,取消標記
		if (gameObject.transform.position.x== hitPoint.x && gameObject.transform.position.y== hitPoint.y)
		{
			clicked = false;
			//默認停止顯示正面或反面
			anim.SetFloat("move X", 0);
			anim.SetFloat("move Y", lookDirection.y);
			anim.SetFloat("runspeed", 0);
			Debug.Log(lookDirection);
		}
		//如果在自動前往目的地時,按下了方向鍵,撤銷這次自動導航,取消標記
		if(Input.GetAxisRaw("Horizontal")!=0||Input.GetAxisRaw("Vertical")!=0)
		{
			clicked = false;
		}

		//如果這次自動導航未被打斷,並且未結束,標記仍然存在,則為運動中的動畫狀態集賦值,結束后回到運動前的朝向
		if (clicked == true && moveDirection.x != 0 && moveDirection.y != 0)
		{
			//為動畫集賦值
			//狀態集的切換由運動矢量決定
			anim.SetFloat("move X", lookDirection.x);
			anim.SetFloat("move Y", lookDirection.y);
			anim.SetFloat("runspeed", moveDirection.magnitude);
			Debug.Log(lookDirection);
		}
	}
}

鼠標導航狀態的判斷

到達目的地、則結束這次自動導航,並正確顯示結束動畫(停止后人物朝向與運動一致)

在到達前按下了方向鍵,撤銷這次自動導航

到達前,並且未撤銷導航,為動畫狀態集賦值,正確顯示導航過程中的動畫(運動中人物朝向與運動一致)

注意:該腳本必須配合以下代碼使用,不然會有極其不良好的體驗。

點擊按鍵的時候,必須要取消自動導航,不然影響操作。

代碼如下,放在按鈕的函數里即可

        //取消點擊按鈕造成的不必要移動
        Follow.autonavi = false;

 

附完整教程:

Unity2d Rubys Adventure 課程設計報告


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM