代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Spine;
using Spine.Unity;
public class TankMoveTest : MonoBehaviour
{
public GameObject 左履带;
public GameObject 右履带;
public GameObject 车体;
public SkeletonAnimation 点击动画;
[SerializeField] private float 车体转速 = 30;
[SerializeField] private float 前进速度 = 3;
[SerializeField] private float 履带动画速度 = 1;
Material 左履带材质, 右履带材质;
Tween 左履带前进动画, 左履带后退动画, 右履带前进动画, 右履带后退动画;
Vector3 点击位置;
void Start()
{
Application.targetFrameRate = 30;//限制帧率
左履带材质 = 左履带.GetComponent<Renderer>().material;
右履带材质 = 右履带.GetComponent<Renderer>().material;
//用材质的UV偏移移动履带贴图
左履带前进动画 = 左履带材质.DOOffset(new Vector2(履带动画速度, 0), 1).SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental).Pause();
左履带后退动画 = 左履带材质.DOOffset(new Vector2(-履带动画速度, 0), 1).SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental).Pause();
右履带前进动画 = 右履带材质.DOOffset(new Vector2(履带动画速度, 0), 1).SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental).Pause();
右履带后退动画 = 右履带材质.DOOffset(new Vector2(-履带动画速度, 0), 1).SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental).Pause();
}
void Update()
{
if (Input.GetMouseButtonDown(1))//按下鼠标右键执行一次
{
/*从摄像机向鼠标方向发射射线,获取鼠标位置*/
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
LayerMask mask = 1 << (LayerMask.NameToLayer("Floor"));
/*Raycast参数:
[1]射线方向
[2]碰撞到的对象信息
[3]射线长度,Mathf.Infinity为无限远
[4]遮罩图层,不检测其他图层的物体
*/
if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask.value))
{
Debug.DrawLine(ray.origin, hit.point, Color.green);//在编辑器视图中绘制射线
点击位置 = hit.point;
点击动画.transform.position = new Vector3(点击位置.x, 0.1f, 点击位置.z);
点击动画.AnimationState.SetAnimation(0, "animation", false);//播放点击动画
/*差乘判断目标位置在车头左边还是右边*/
Vector3 direction = 点击位置 - 车体.transform.position;
var cross = Vector3.Cross(车体.transform.forward, direction);
if (cross.y < 0)//左
{
履带停止();
左履带后退();
右履带前进();
}
else//右
{
履带停止();
左履带前进();
右履带后退();
}
//原地向目标点方向转动
车体.transform.DOLookAt(点击位置, 车体转速, AxisConstraint.Y , Vector3.up).SetEase(Ease.InOutSine).SetSpeedBased().OnComplete(RotateCallback);
}
}
}
public void 左履带前进()
{
if(左履带后退动画.IsPlaying())
{
左履带后退动画.TogglePause();
}
左履带材质.DOOffset(new Vector2(0, 0), 0);
左履带前进动画.TogglePause();
}
public void 左履带后退()
{
if (左履带前进动画.IsPlaying())
{
左履带前进动画.TogglePause();
}
左履带材质.DOOffset(new Vector2(0, 0), 0);
左履带后退动画.TogglePause();
}
public void 右履带前进()
{
if (右履带后退动画.IsPlaying())
{
右履带后退动画.TogglePause();
}
右履带材质.DOOffset(new Vector2(0, 0), 0);
右履带前进动画.TogglePause();
}
public void 右履带后退()
{
if (右履带前进动画.IsPlaying())
{
右履带前进动画.TogglePause();
}
右履带材质.DOOffset(new Vector2(0, 0), 0);
右履带后退动画.TogglePause();
}
public void 履带停止()
{
if (右履带前进动画.IsPlaying())
{
右履带前进动画.TogglePause();
}
if (右履带后退动画.IsPlaying())
{
右履带后退动画.TogglePause();
}
右履带材质.DOOffset(new Vector2(0, 0), 0);
if (左履带前进动画.IsPlaying())
{
左履带前进动画.TogglePause();
}
if (左履带后退动画.IsPlaying())
{
左履带后退动画.TogglePause();
}
左履带材质.DOOffset(new Vector2(0, 0), 0);
}
void RotateCallback()//旋转完成回调
{
履带停止();
/*旋转完成后等待0.1s*/
float timer = 0;
DOTween.To(() => timer, x => timer = x, 1, 0.1f).OnStepComplete(() =>
{
左履带前进();
右履带前进();
车体.transform.DOMove(点击位置, 前进速度).SetEase(Ease.InOutSine).SetSpeedBased().OnComplete(MoveCallback);
}).SetLoops(0);
}
void MoveCallback()//前进完成回调
{
履带停止();
}
}
本来只是测试材质UV偏移的