相机只是一名士兵的孩子,目标也是这名士兵。
脚本附在相机上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public Transform target;
public float speed = 0.1f;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
transform.RotateAround(target.transform.position, new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
}
}
但现在我想做两件事。使相机围绕整个士兵而不仅仅是特定的一个旋转。并且当它面向士兵时,使相机慢慢停止。现在开始游戏后相机就落后了。
如果为true,则使用bool标志使摄像机围绕士兵旋转,直到面对他们然后停止旋转并继续与士兵一起移动。
如果未经检查,则假设相机在焊料周围旋转,则无法停止。
更新到目前为止我尝试的内容:
此代码将使其围绕所有士兵旋转,并且工作正常:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public float speed = 0.1f;
private List<GameObject> Soldiers = new List<GameObject>();
// Use this for initialization
void Start()
{
Soldiers.AddRange(GameObject.FindGameObjectsWithTag("Soldier"));
}
// Update is called once per frame
void Update()
{
RotateAround();
}
private void RotateAround()
{
transform.RotateAround(GetAverageLocationOfSoliders(), new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in Soldiers)
total += soldier.transform.position;
return total / Soldiers.Count(); // Assuming Soldiers is List<Soldier>
}
}
然后我尝试添加一个slowDown bool标志变量,但是我搞砸了它并且它根本不起作用。
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public float speed = 0.1f;
public bool slowDown = false;
private List<Vector3> SoldiersPositions = new List<Vector3>();
private List<Vector3> SoldiersFacingDirection = new List<Vector3>();
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
RotateAround();
}
private void RotateAround()
{
var getSoldiers = GameObject.FindGameObjectsWithTag("Soldier");
foreach (GameObject soldier in getSoldiers)
{
SoldiersPositions.Add(soldier.transform.position);
SoldiersFacingDirection.Add(soldier.transform.forward);
}
var Center = GetAverageLocationOfSoliders();
var FacingDirections = GetAverageFacingDirectionOfSoldiers();
if (slowDown == true)
{
var D = transform.position - Center;
var CamAngle = Vector3.Angle(D, FacingDirections);
speed = speed - CamAngle;
}
transform.RotateAround(Center, new Vector3(0, 1, 0), 100 * Time.deltaTime * speed);
SoldiersPositions = new List<Vector3>();
SoldiersFacingDirection = new List<Vector3>();
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in SoldiersPositions)
total += soldier;
return total / SoldiersPositions.Count(); // Assuming Soldiers is List<Soldier>
}
private Vector3 GetAverageFacingDirectionOfSoldiers()
{
var total = new Vector3();
foreach (var soldierfacingdir in SoldiersFacingDirection)
total += soldierfacingdir;
return total / SoldiersFacingDirection.Count();
}
}
我不确定只有旋转的第一个代码示例是否与我编写它的方式相同。它工作但不确定这是否是一个很好的方法来执行代码?
在我看来,在第一个代码中,只有旋转相机有点摇晃或口吃,我的意思是相机在旋转时不能平滑移动。在编辑器的游戏视图中几乎很难看到,但你可以在我认为的场景视图中看到它。
我调用RotateAround()的原因;在更新中,士兵们正在不停地向前走。
我该怎么做slowDown部分?
更新2:
现在这是完整的男女同校:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
[Header("Spin")]
public bool spin = false;
public Vector3 Direction;
[Range(0, 300)]
public float speed = 10f;
public bool randomSpeed = false;
public bool randomDirection = false;
[Range(0f, 100f)]
public float timeDirChange;
public Vector3 defaultDirection;
[Space(5)]
[Header("Move in circles")]
public bool moveInCircles = true;
public GameObject rotateAroundTarget;
public Vector3 axis;//by which axis it will rotate. x,y or z.
public float rotationSpeed; //or the speed of rotation.
public float upperLimit, lowerLimit, delay;// upperLimit & lowerLimit: heighest & lowest height;
public bool randomHeight = false;
public bool stopRotatingWhenFacing = false;
private float height, prevHeight, time;//height:height it is trying to reach(randomly generated); prevHeight:stores last value of height;delay in radomness;
[Space(5)]
[Header("Follow objects")]
public GameObject[] objectsToFollow;
public bool randomFollow;
private float nextRotationTime = 0f;
private int counter = 0;
private List<GameObject> Soldiers = new List<GameObject>();
// Use this for initialization
void Start()
{
Soldiers.AddRange(GameObject.FindGameObjectsWithTag("Soldier"));
}
private void Update()
{
if (randomSpeed)
{
speed = UnityEngine.Random.Range(0, 300);
}
if (spin)
{
if (randomDirection == false)
{
nextRotationTime = 0;
timeDirChange = 0;
Direction = defaultDirection;
}
else
{
if (Time.time > nextRotationTime)
{
nextRotationTime += timeDirChange;
RandomDirection();
}
}
transform.Rotate(Direction, speed * Time.deltaTime);
}
else
{
timeDirChange = 0;
randomDirection = false;
randomSpeed = false;
}
if (moveInCircles)
{
MoveInCircles();
}
}
private void RandomDirection()
{
Direction = new Vector3(UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1));
while (Direction == new Vector3(0, 0, 0))
{
counter++;
Direction = new Vector3(UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1));
if (counter == 2)
{
Direction = new Vector3(1, 0, 0);
break;
}
}
counter = 0;
}
private void MoveInCircles()
{
var F = GetAverageDirectionsOfSoliders();
var D = transform.position - GetAverageLocationOfSoliders();
var angle = Vector3.Angle(D, F);
if (angle < 5f)
{
rotationSpeed -= 0.1f;
}
transform.RotateAround(GetAverageLocationOfSoliders(), axis, rotationSpeed);
time += Time.deltaTime;
//Sets value of 'height' randomly within 'upperLimit' & 'lowerLimit' after delay
if (time > delay)
{
prevHeight = height;
if (randomHeight)
{
height = UnityEngine.Random.Range(lowerLimit, upperLimit);
}
time = 0;
}
if (randomHeight == false)
{
height = transform.position.y;
}
if (randomHeight)
{
//Mathf.Lerp changes height from 'prevHeight' to 'height' gradually (smooth transition)
transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time), transform.position.z);
}
else
{
transform.position = new Vector3(transform.position.x, height, transform.position.z);
}
}
private Vector3 GetAverageLocationOfSoliders()
{
var total = new Vector3();
foreach (var soldier in Soldiers)
{
total += soldier.transform.position;
}
return total / Soldiers.Count(); // Assuming Soldiers is List<Soldier>
}
private Vector3 GetAverageDirectionsOfSoliders()
{
var totalf = new Vector3();
foreach (var soldier in Soldiers)
{
totalf += soldier.transform.forward;
}
return totalf / Soldiers.Count();
}
}
RotateAround部分工作正常:
transform.RotateAround(GetAverageLocationOfSoliders(), axis, rotationSpeed);
但减速部分不起作用。当相机对着士兵时,它并没有减速。
这是我计算所有士兵的平均transform.forward矢量的方法:
private Vector3 GetAverageDirectionsOfSoliders()
{
var totalf = new Vector3();
foreach (var soldier in Soldiers)
{
totalf += soldier.transform.forward;
}
return totalf / Soldiers.Count();
}
然后在MoveInCircles方法中我做了:
var F = GetAverageDirectionsOfSoliders();
var D = transform.position - GetAverageLocationOfSoliders();
var angle = Vector3.Angle(D, F);
if (angle < 5f)
{
rotationSpeed -= 0.1f;
}
但它永远不会上线:
rotationSpeed -= 0.1f;
答案 0 :(得分:3)
围绕所有士兵旋转:
N
士兵数量)面对士兵时,请将相机放慢速度。前:
transform.forward
向量。我们称这个向量为F
。这是公平的,因为你的所有士兵通常都面临着这个要求甚至有意义的相同方向。D
,这是士兵的方向。相机的中心。这很简单:D = camera.transform.position - soldiersCenter
D
找到F
和Vector3.Angle()
之间的锐角。如果此角度低于某个阈值,请减小相机的moveSpeed
。实际代码很容易编写,但我会让你练习。如果您需要任何帮助,请告诉我
答案 1 :(得分:1)
从它的声音来看,似乎你已经能够围绕一个士兵进行环绕,所以不止一个,只需要取其位置的平均值。
伪码:
transform.RotateAround(GetAverageLocationOfSoliders(), ...);
...
private static Vector3 GetAverageLocationOfSoliders
{
var total = new Vector3();
foreach(var soldier in Soldiers)
total += soldier.transform.position;
return total / Soliders.Count(); // Assuming Soldiers is List<Soldier>
}
现在,Vector3
可能没有像Vector3 += Vector3
或Vector3 / int
这样的内容,但如果是这样,那么只需创建自己的方法就可以手动执行此操作(添加{{} 1}}和vectorA.x + vectorB.x
等等。
当相机在前面停下来时,这有点棘手。您可能需要先进行一些检查以确保它们都具有相同的旋转,然后检查每个vectorA.x / num
,如果相机的旋转外观指向其中一个士兵。
但是,如果你希望它减速,那么,不要检查Update
是否可以指向士兵,而是检查它是否可以指向相机的某些lookAtRotation
旋转,如:
伪代码:
offset
然后,如果找到一个,你可以使用你的速度lookRotation(transform.Rotation + offset) // Use something like this to find Soldiers[0]
来恢复速度为0.
您还必须以某种方式维护Lerp
或List<Soldier>
。