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 课程设计报告

猜你喜欢

转载自blog.csdn.net/weixin_43673589/article/details/106562238
今日推荐