usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassEnemy:MonoBehaviour{privateTransformplayer;privateListpath=newList();privateintpathIndex=0;privatefloatmoveSpeed=5f;privatefloatnextNodeDistance=1f;privatevoidStart(){player=GameObject.FindGameObjectWithTag("Player").transform;}privatevoidUpdate(){if(path.Count>0&&pathIndex<path.Count){Vector3direction=(path[pathIndex]-transform.position).normalized;transform.position+=directionTime.deltaTimemoveSpeed;if(Vector3.Distance(transform.position,path[pathIndex])<nextNodeDistance){pathIndex++;}
}else{path=AStarPathfinding.FindPath(transform.position,player.position);pathIndex=0;}}}
参考GPT和自己的思路:这段代码是一个敌人角色的脚本,包括了敌人角色移动的逻辑以及路径寻找的算法。具体来说,代码中使用了A(A-Star)算法进行路径寻找,从当前敌人位置到玩家位置之间的最短路径。在 Start() 函数中,敌人角色会寻找场景中带有 "Player" 标签的对象,并将其位置信息保存在变量 player 中。在 Update() 函数中,如果路径 path 不为空,且 pathIndex 值小于 path 集合的长度,则敌人角色按照路径上的节点依次移动,直到到达最终节点。如果敌人角色到达了当前节点,则将 pathIndex 加一,再进行下一个节点的寻找和移动。如果当前路径为空,则执行 A 路径寻找算法以生成新的路径。值得注意的是,变量 nextNodeDistance 控制了敌人角色到达路径节点的距离阈值,超过这个距离后将移动到路径上的下一个节点。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy:MonoBehaviour{
//首先,这是一个unity3d的脚本,语言是c#
//这里定义了一个类Enemy,继承MonoBehaviour,这样就可以挂在物体下面
private Transform player;
private List path=new List();
private int pathIndex=0;
private float moveSpeed=5f;
private float nextNodeDistance=1f;
private void Start(){
player=GameObject.FindGameObjectWithTag("Player").transform;
//start函数在脚本初始化时执行一次
//这里先获取Player物体的transform对象,保存在player这个变量里
}
private void Update(){
//update在每一帧执行
//判断参数,进入if或else
if(path.Count>0 && pathIndex<path.Count)
{
//获取方向
Vector3 direction=(path[pathIndex]-transform.position).normalized;
//修改位置,位置+=速度
transform.position+=directionTime.deltaTimemoveSpeed;
//判断距离
if(Vector3.Distance(transform.position,path[pathIndex])<nextNodeDistance)
{pathIndex++;}
}
else
{
//寻路
path=AStarPathfinding.FindPath(transform.position,player.position);
pathIndex=0;
}
//整个udate里实现的是自动寻路脚本,如果已经寻到路了,那么就根据路线行进,否则先执行寻路
}
}
这里先直接给出测试代码 和 结果:
缓存 Time.deltaTime 之前:
缓存 Time.deltaTime 之后:
可以看出,在每帧 100000 次运算下,缓存 Time.deltaTime 后,优化了 20ms 左右
原文没有给出该优化原理的解释。个人猜测为,每次获取 Time.deltaTime 时 Unity 都会重新计算一次 deltaTime,但这是没有必要的,因为我们只要确保 deltaTime 一帧能更新一次即可。
回答:
Time.deltaTime是Unity中一个可以返回当前程序每一帧与上一帧之间的时间差的属性。它在游戏编程中被广泛使用,可以用来测量游戏对象的移动速度、处理动画、在时间间隔内完成某个事件等等。
例如,如果我们希望在游戏中以每秒1次的频率完成某个事件,可以利用Time.deltaTime属性进行计时,代码如下:
private float timer = 0;
private float delayTime = 1;
private void Update()
{
timer += Time.deltaTime;
if(timer >= delayTime)
{
//你要做的事...
timer = 0;
}
}
除此之外,Time.deltaTime还常常与每帧的移动量结合使用,例如在模拟重力等物理效果时。下面是一个模拟重力的示例代码:
private void VerticalCollisions(ref Vector3 velocity){//竖直方向的射线检测
float directionY = Mathf.Sign (velocity.y);//通过y来判断是跳跃还是下落
float rayLength = Mathf.Abs (velocity.y)+skillWidth;//射线的长度
for (int i = 0; i < verticalRayCount; i++) {
Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft;//通过方向来选择射线的起点
rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);//加上x方向的偏移
RaycastHit2D hit = Physics2D.Raycast (rayOrigin,Vector2.up*directionY,rayLength,collisionMask);//检测碰撞
Debug.DrawRay (rayOrigin,Vector2.up*directionY*rayLength,Color.red);
if (hit) {//如果发生碰撞
velocity.y = (hit.distance-skillWidth)*directionY;//移动距离变为碰撞点距物体的距离
rayLength = hit.distance;
}
}
}
private void Move(Vector3 velocity){//移动
UpdateRaycastOrigins ();//更新射线源点
if(velocity.x!=0)
HorizontalCollisions(ref velocity);
if(velocity.y!=0)
VerticalCollisions (ref velocity);//竖直方向检测碰撞
transform.Translate (velocity * Time.deltaTime);//移动,并结合Time.deltaTime计算每帧移动的距离
}