C# 为什么飞行摄影机从不在地形上的航路点之间飞行?
我有3个脚本连接到一个我称之为Fly camera的相机。 有点长,但所有3个脚本都在一起工作: 首先,脚本LookAtCamera:C# 为什么飞行摄影机从不在地形上的航路点之间飞行?,c#,unity3d,C#,Unity3d,我有3个脚本连接到一个我称之为Fly camera的相机。 有点长,但所有3个脚本都在一起工作: 首先,脚本LookAtCamera: using System.Collections; using System.Collections.Generic; using UnityEngine; public class LookAtCamera : MonoBehaviour { //values that will be set in the Inspector public
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtCamera : MonoBehaviour
{
//values that will be set in the Inspector
public Transform target;
public float RotationSpeed;
//values for internal use
private Quaternion _lookRotation;
private Vector3 _direction;
// Update is called once per frame
void Update()
{
//find the vector pointing from our position to the target
if (target)
_direction = (target.position - transform.position).normalized;
//create the rotation we need to be in to look at the target
if (_direction != Vector3.zero)
_lookRotation = Quaternion.LookRotation(_direction);
//rotate us over time according to speed until we are in the required rotation
transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * RotationSpeed);
}
}
下一个FlyToOverTerrain:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlyToOverTerrain : MonoBehaviour
{
public Transform target;
public float desiredHeight = 10f;
public float flightSmoothTime = 10f;
public float maxFlightspeed = 10f;
public float flightAcceleration = 1f;
public float levelingSmoothTime = 0.5f;
public float maxLevelingSpeed = 10000f;
public float levelingAcceleration = 2f;
private Vector3 flightVelocity = Vector3.zero;
private float heightVelocity = 0f;
private void LateUpdate()
{
Vector3 position = transform.position;
float currentHeight = position.y;
if (target && flightAcceleration > float.Epsilon)
{
position = Vector3.SmoothDamp(position, target.position, ref flightVelocity, flightSmoothTime / flightAcceleration, maxFlightspeed, flightAcceleration * Time.deltaTime);
}
if (levelingAcceleration > float.Epsilon)
{
float targetHeight = Terrain.activeTerrain.SampleHeight(position) + desiredHeight;
position.y = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, levelingSmoothTime / levelingAcceleration, maxLevelingSpeed, levelingAcceleration * Time.deltaTime);
}
transform.position = position;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PatrolData
{
public Transform target = null;
public float minDistance = 5f;
public float lingerDuration = 5f;
public float desiredHeight = 10f;
public float flightSmoothTime = 10f;
public float maxFlightspeed = 10f;
public float flightAcceleration = 1f;
public float levelingSmoothTime = 0.5f;
public float maxLevelingSpeed = 10000f;
public float levelingAcceleration = 2f;
}
public class PatrolOverTerrain : MonoBehaviour
{
public FlyToOverTerrain flyOverTerrain;
public LookAtCamera lookAtCamera;
public enum PatrolMode { Clamp, Wrap, PingPong };
public PatrolData[] patrolPoints;
public PatrolMode mode = PatrolMode.Wrap;
private int iterator = 0;
private int index = 0;
private float lingerDuration = 0f;
private int overallLength = 0;
public bool autoFreedomPatrol = false;
public List<GameObject> Targets = new List<GameObject>();
public string tagName;
public Vector3 distanceFromTarget;
public void Start()
{
if (tagName != "")
{
GameObject[] tempObj = GameObject.FindGameObjectsWithTag(tagName);
for (int i = 0; i < tempObj.Length; i++)
{
//Add to list only if it does not exist
if (!Targets.Contains(tempObj[i]))
{
Targets.Add(tempObj[i]);
}
}
//Get the current Size
if (tempObj != null)
{
overallLength = Targets.Count;
}
GeneratePatrolPoints();
}
}
private void OnEnable()
{
if (patrolPoints.Length > 0)
{
lingerDuration = patrolPoints[index].lingerDuration;
}
}
private void Update()
{
int length = patrolPoints.Length;
if (!flyOverTerrain) return;
if (patrolPoints.Length < 1) return;
if (index < 0) return;
var patrol = patrolPoints[index];
if (lingerDuration <= 0)
{
iterator++;
switch (mode)
{
case PatrolMode.Clamp:
index = (iterator >= length) ? -1 : iterator;
break;
case PatrolMode.Wrap:
iterator = Modulus(iterator, length);
index = iterator;
break;
case PatrolMode.PingPong:
index = PingPong(iterator, length);
break;
}
if (index < 0) return;
patrol = patrolPoints[index];
flyOverTerrain.target = patrol.target;
flyOverTerrain.desiredHeight = patrol.desiredHeight;
flyOverTerrain.flightSmoothTime = patrol.flightSmoothTime;
flyOverTerrain.maxFlightspeed = patrol.maxFlightspeed;
flyOverTerrain.flightAcceleration = patrol.flightAcceleration;
flyOverTerrain.levelingSmoothTime = patrol.levelingSmoothTime;
flyOverTerrain.maxLevelingSpeed = patrol.maxLevelingSpeed;
flyOverTerrain.levelingAcceleration = patrol.levelingAcceleration;
lookAtCamera.target = patrol.target;
lookAtCamera.RotationSpeed = 3;
lingerDuration = patrolPoints[index].lingerDuration;
}
Vector3 targetOffset = Vector3.zero;
if ((bool)patrol.target)
{
targetOffset = transform.position - patrol.target.position;
}
float sqrDistance = patrol.minDistance * patrol.minDistance;
if (targetOffset.sqrMagnitude <= sqrDistance)
{
flyOverTerrain.target = null;
lookAtCamera.target = null;
lingerDuration -= Time.deltaTime;
}
else
{
flyOverTerrain.target = patrol.target;
lookAtCamera.target = patrol.target;
}
distanceFromTarget = transform.position - patrol.target.position;
}
private int PingPong(int baseNumber, int limit)
{
if (limit < 2) return 0;
return limit - Mathf.Abs(limit - Modulus(baseNumber, limit + (limit - 2)) - 1) - 1;
}
private int Modulus(int baseNumber, int modulus)
{
return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
}
public void GeneratePatrolPoints()
{
patrolPoints = new PatrolData[Targets.Count];
for (int i = 0; i < patrolPoints.Length; i++)
{
patrolPoints[i] = new PatrolData();
patrolPoints[i].target = Targets[i].transform;
patrolPoints[i].minDistance = 30f;
patrolPoints[i].lingerDuration = 3f;
patrolPoints[i].desiredHeight = 20f;
patrolPoints[i].flightSmoothTime = 10f;
patrolPoints[i].maxFlightspeed = 10f;
patrolPoints[i].flightAcceleration = 3f;
patrolPoints[i].levelingSmoothTime = 0.5f;
patrolPoints[i].maxLevelingSpeed = 10000f;
patrolPoints[i].levelingAcceleration = 2f;
}
}
}
最后一点:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlyToOverTerrain : MonoBehaviour
{
public Transform target;
public float desiredHeight = 10f;
public float flightSmoothTime = 10f;
public float maxFlightspeed = 10f;
public float flightAcceleration = 1f;
public float levelingSmoothTime = 0.5f;
public float maxLevelingSpeed = 10000f;
public float levelingAcceleration = 2f;
private Vector3 flightVelocity = Vector3.zero;
private float heightVelocity = 0f;
private void LateUpdate()
{
Vector3 position = transform.position;
float currentHeight = position.y;
if (target && flightAcceleration > float.Epsilon)
{
position = Vector3.SmoothDamp(position, target.position, ref flightVelocity, flightSmoothTime / flightAcceleration, maxFlightspeed, flightAcceleration * Time.deltaTime);
}
if (levelingAcceleration > float.Epsilon)
{
float targetHeight = Terrain.activeTerrain.SampleHeight(position) + desiredHeight;
position.y = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, levelingSmoothTime / levelingAcceleration, maxLevelingSpeed, levelingAcceleration * Time.deltaTime);
}
transform.position = position;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PatrolData
{
public Transform target = null;
public float minDistance = 5f;
public float lingerDuration = 5f;
public float desiredHeight = 10f;
public float flightSmoothTime = 10f;
public float maxFlightspeed = 10f;
public float flightAcceleration = 1f;
public float levelingSmoothTime = 0.5f;
public float maxLevelingSpeed = 10000f;
public float levelingAcceleration = 2f;
}
public class PatrolOverTerrain : MonoBehaviour
{
public FlyToOverTerrain flyOverTerrain;
public LookAtCamera lookAtCamera;
public enum PatrolMode { Clamp, Wrap, PingPong };
public PatrolData[] patrolPoints;
public PatrolMode mode = PatrolMode.Wrap;
private int iterator = 0;
private int index = 0;
private float lingerDuration = 0f;
private int overallLength = 0;
public bool autoFreedomPatrol = false;
public List<GameObject> Targets = new List<GameObject>();
public string tagName;
public Vector3 distanceFromTarget;
public void Start()
{
if (tagName != "")
{
GameObject[] tempObj = GameObject.FindGameObjectsWithTag(tagName);
for (int i = 0; i < tempObj.Length; i++)
{
//Add to list only if it does not exist
if (!Targets.Contains(tempObj[i]))
{
Targets.Add(tempObj[i]);
}
}
//Get the current Size
if (tempObj != null)
{
overallLength = Targets.Count;
}
GeneratePatrolPoints();
}
}
private void OnEnable()
{
if (patrolPoints.Length > 0)
{
lingerDuration = patrolPoints[index].lingerDuration;
}
}
private void Update()
{
int length = patrolPoints.Length;
if (!flyOverTerrain) return;
if (patrolPoints.Length < 1) return;
if (index < 0) return;
var patrol = patrolPoints[index];
if (lingerDuration <= 0)
{
iterator++;
switch (mode)
{
case PatrolMode.Clamp:
index = (iterator >= length) ? -1 : iterator;
break;
case PatrolMode.Wrap:
iterator = Modulus(iterator, length);
index = iterator;
break;
case PatrolMode.PingPong:
index = PingPong(iterator, length);
break;
}
if (index < 0) return;
patrol = patrolPoints[index];
flyOverTerrain.target = patrol.target;
flyOverTerrain.desiredHeight = patrol.desiredHeight;
flyOverTerrain.flightSmoothTime = patrol.flightSmoothTime;
flyOverTerrain.maxFlightspeed = patrol.maxFlightspeed;
flyOverTerrain.flightAcceleration = patrol.flightAcceleration;
flyOverTerrain.levelingSmoothTime = patrol.levelingSmoothTime;
flyOverTerrain.maxLevelingSpeed = patrol.maxLevelingSpeed;
flyOverTerrain.levelingAcceleration = patrol.levelingAcceleration;
lookAtCamera.target = patrol.target;
lookAtCamera.RotationSpeed = 3;
lingerDuration = patrolPoints[index].lingerDuration;
}
Vector3 targetOffset = Vector3.zero;
if ((bool)patrol.target)
{
targetOffset = transform.position - patrol.target.position;
}
float sqrDistance = patrol.minDistance * patrol.minDistance;
if (targetOffset.sqrMagnitude <= sqrDistance)
{
flyOverTerrain.target = null;
lookAtCamera.target = null;
lingerDuration -= Time.deltaTime;
}
else
{
flyOverTerrain.target = patrol.target;
lookAtCamera.target = patrol.target;
}
distanceFromTarget = transform.position - patrol.target.position;
}
private int PingPong(int baseNumber, int limit)
{
if (limit < 2) return 0;
return limit - Mathf.Abs(limit - Modulus(baseNumber, limit + (limit - 2)) - 1) - 1;
}
private int Modulus(int baseNumber, int modulus)
{
return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
}
public void GeneratePatrolPoints()
{
patrolPoints = new PatrolData[Targets.Count];
for (int i = 0; i < patrolPoints.Length; i++)
{
patrolPoints[i] = new PatrolData();
patrolPoints[i].target = Targets[i].transform;
patrolPoints[i].minDistance = 30f;
patrolPoints[i].lingerDuration = 3f;
patrolPoints[i].desiredHeight = 20f;
patrolPoints[i].flightSmoothTime = 10f;
patrolPoints[i].maxFlightspeed = 10f;
patrolPoints[i].flightAcceleration = 3f;
patrolPoints[i].levelingSmoothTime = 0.5f;
patrolPoints[i].maxLevelingSpeed = 10000f;
patrolPoints[i].levelingAcceleration = 2f;
}
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
[系统可序列化]
公共类数据
{
公共转换目标=null;
公众漂浮距离=5f;
公共浮动持续时间=5f;
公共浮子所需高度=10f;
公共浮动飞行时间=10f;
公共浮点数maxFlightspeed=10f;
公共浮标飞行加速度=1f;
公共浮动水平平滑时间=0.5f;
公共浮动最大水平速度=10000f;
公共浮动水平加速度=2f;
}
公共类巡逻员:单行为
{
公共立交桥天桥天桥天桥天桥天桥;
公众摄像机;
公共枚举模式{夹紧、缠绕、乒乓球};
公共巡逻数据[]巡逻点;
公共巡逻模式=巡逻模式.Wrap;
私有整数迭代器=0;
私有整数指数=0;
私有浮动持续时间=0f;
私有整数总长度=0;
public bool autoFreedomPatrol=false;
公共列表目标=新列表();
公共字符串标记名;
公共向量3与目标的距离;
公开作废开始()
{
如果(标记名!=“”)
{
GameObject[]tempObj=GameObject.FindGameObjectsWithTag(标记名);
for(int i=0;i0)
{
lingerDuration=巡逻点[索引]。lingerDuration;
}
}
私有void更新()
{
int length=巡逻点。长度;
如果(!flyOverTerrain)返回;
如果(巡逻点长度<1)返回;
如果(指数<0)返回;
var巡逻=巡逻点[指数];
如果(lingerDuration=长度)?-1:迭代器;
打破
案例模式。换行:
迭代器=模(迭代器,长度);
索引=迭代器;
打破
乒乓球:
索引=乒乓球(迭代器,长度);
打破
}
如果(指数<0)返回;
巡逻=巡逻点[指数];
flyOverTerrain.target=巡逻.target;
flyOverTerrain.desiredHeight=巡逻.desiredHeight;
flyOverTerrain.flightSmoothTime=巡逻.flightSmoothTime;
flyOverTerrain.maxFlightspeed=patrol.maxFlightspeed;
flyOverTerrain.flightAcceleration=巡逻.flightAcceleration;
flyOverTerrain.levelingSmoothTime=巡逻.levelingSmoothTime;
flyOverTerrain.maxLevelingSpeed=patrol.maxLevelingSpeed;
立交桥坡度加速度=巡逻坡度加速度;
lookAtCamera.target=patrol.target;
lookAtCamera.RotationSpeed=3;
lingerDuration=巡逻点[索引]。lingerDuration;
}
Vector3 targetOffset=Vector3.0;
如果((布尔)巡逻目标)
{
targetOffset=transform.position-patrol.target.position;
}
float sqrDistance=patrol.minDistance*patrol.minDistance;
如果(targetOffset.sqrMagnitude,我认为问题出在
if (targetOffset.sqrMagnitude <= sqrDistance)
{
flyOverTerrain.target = null;
lookAtCamera.target = null;
lingerDuration -= Time.deltaTime;
}
else
{
flyOverTerrain.target = patrol.target;
lookAtCamera.target = patrol.target;
}
可能永远不会匹配
我想你宁愿在Update
运行的每一帧中减少它,也不愿将它移出该块
我还建议你使用
if(Vector3.Distance(transform.position, patrol.target.position) <= patrol.minDistance)
if(矢量3.距离(变换.位置,巡逻.目标.位置)似乎在场景中的其他地方,那些目标
对象被破坏了……顺便问一下,如果每个元素的值相同,那么为什么要存储每个航路点的所有值?@derHugo在我使用实例化对象的SphereBuilder脚本时是这样的。所以现在我不使用它,只使用created 4个立方体并将它们标记为目标,现在它们没有被破坏和丢失。但是相机只移动到第一个立方体,而没有继续移动到其他立方体。(这就是为什么我还删除了问题中的屏幕截图,因为丢失的破坏问题与此无关)@derHugo现在它们有相同的值,但当我使用我的脚本SphereBuilder或其他实例化脚本时,我发现它实例化了具有随机位置、旋转和缩放的对象。我发现了诸如desiredHeight
flightSmoothTime
等值。问题出在我的集合上脚本检查器中的Ting会飞到地形上。可变的所需高度设置为10,但立方体的高度为0。一旦将所需高度更改为0,或者将立方体高度更改为更高,则效果会非常理想。