using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;
public class WayPoints : MonoBehaviour {
public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 1f;
public float rotationSpeed = 1f;
private Transform myTransform;
private int targetsIndex = 0;
private Vector3 originalPosition;
public float walkSpeed = 15f;
void Awake()
{
myTransform = transform;
}
// Use this for initialization
void Start()
{
waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");
originalPosition = myTransform.position;
}
// Update is called once per frame
void Update()
{
if (MyCommands.walkbetweenwaypoints == true)
{
WayPointsAI();
}
DrawLinesInScene();
}
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
float distance = Vector3.Distance(myTransform.position, target.transform.position);
myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed * Time.deltaTime);
//move towards the player
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
if (distance < 2f)
targetsIndex++;
if (distance < 5f)
{
moveSpeed = 5;
}
else
{
}
}
void DrawLinesInScene()
{
// draw lines between each checkpoint //
for (int i = 0; i < waypoints.Length - 1; i++)
{
Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
}
// draw a line between the original transform start position
// and the current transform position //
Debug.DrawLine(originalPosition, transform.position, Color.red);
// draw a line between current transform position and the next waypoint target
// each time reached a waypoint.
if (target != null)
Debug.DrawLine(target.transform.position, myTransform.position, Color.green);
}
}
我希望当玩家/游戏对象接近下一个航点时,他会减速,然后当他通过航点时,旋转到下一个航点速度uo到原来的减速速度之前。
所以我补充道:
if (distance < 5f)
{
moveSpeed = 5;
}
else
{
}
但首先我不确定< 5
是否远远不足以让它变得缓慢,但让我们说一秒钟它是否足以让我如何加快速度到达路点后转向下一个?我可以将原始速度存储在Start
函数中的某个变量中,但可能存在用户在游戏运行时更改速度的情况,因此在Start函数中存储原始速度将不会始终有效
如何在阵列航点半径中找到每个航路点? 现在我把它设置为距离&lt; 2
if (distance < 2f)
targetsIndex++;
但是如果航点对象半径大于2则玩家将停留在此航点上。所以我认为反对检查2f应该是像距离&lt; waypoints [i] .radius或如何找到半径。逻辑是找到每个航路点的半径并检查它的半径而不是2f。
修改
这是我的WayPoints脚本。我将一个对撞机和SlowDown脚本添加到路标点数组中的每个航路点:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;
public class WayPoints : MonoBehaviour {
//setters for setting everything in Unity editor
public float moveSpeedWalkSetter = 10f;
public float moveSpeedSlowedWalkSetter = 3f;
//static objects changeable via any script
public static float moveSpeedWalk;
public static float moveSpeedSlowedWalk;
static ThirdPersonCharacter thirdperson;
public GameObject[] waypoints;
public Transform target;
public float rotationSpeed = 1f;
private Transform myTransform;
private int targetsIndex = 0;
private Vector3 originalPosition;
private GameObject[] robots;
public Transform reverseTarget;
private int reverseTargetsIndex = 0;
private Vector3 reverseOriginalPosition;
//public float walkSpeed = 15f;
void Awake()
{
myTransform = transform;
}
// Use this for initialization
void Start()
{
thirdperson = new ThirdPersonCharacter();
moveSpeedWalk = moveSpeedWalkSetter;
moveSpeedSlowedWalk = moveSpeedSlowedWalkSetter;
thirdperson.ChangeSpeed(moveSpeedWalk);
waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");
robots = GameObject.FindGameObjectsWithTag("Robots");
AddColliderToWaypoints();
AddSlowdownScriptToWaypoints();
originalPosition = robots[0].transform.position;
reverseOriginalPosition = robots[1].transform.position;
}
// Update is called once per frame
void Update()
{
if (MyCommands.walkbetweenwaypoints == true)
{
WayPointsAI();
ReverseWayPointsAI();
}
DrawLinesInScene();
}
public static void SetSpeed(float move)
{
thirdperson.ChangeSpeed(move);
}
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
float distance = Vector3.Distance(robots[0].transform.position, target.transform.position);
robots[0].transform.rotation = Quaternion.Slerp(robots[0].transform.rotation, Quaternion.LookRotation(target.position - robots[0].transform.position), rotationSpeed * Time.deltaTime);
//move towards the player
robots[0].transform.position += robots[0].transform.forward * moveSpeedWalk * Time.deltaTime;
if (distance < 2f)
targetsIndex++;
}
private void ReverseWayPointsAI()
{
if (reverseTargetsIndex == 0)
reverseTargetsIndex = waypoints.Length -1;
reverseTarget = waypoints[reverseTargetsIndex].transform;
float distance = Vector3.Distance(robots[1].transform.position, reverseTarget.transform.position);
robots[1].transform.rotation = Quaternion.Slerp(robots[1].transform.rotation, Quaternion.LookRotation(reverseTarget.position - robots[1].transform.position), rotationSpeed * Time.deltaTime);
//move towards the player
robots[1].transform.position += robots[1].transform.forward * moveSpeedWalk * Time.deltaTime;
if (distance < 2f)
reverseTargetsIndex--;
}
void RandomWayPointsAI()
{
}
void DrawLinesInScene()
{
// draw lines between each checkpoint //
for (int i = 0; i < waypoints.Length - 1; i++)
{
Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
}
// draw a line between the original transform start position
// and the current transform position //
Debug.DrawLine(originalPosition, robots[0].transform.position, Color.red);
Debug.DrawLine(originalPosition, robots[1].transform.position, Color.red);
// draw a line between current transform position and the next waypoint target
// each time reached a waypoint.
if (target != null)
Debug.DrawLine(target.transform.position, robots[0].transform.position, Color.green);
if (reverseTarget != null)
Debug.DrawLine(reverseTarget.transform.position, robots[1].transform.position, Color.green);
}
void AddColliderToWaypoints()
{
foreach (GameObject go in waypoints)
{
SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
sc.isTrigger = true;
}
}
void AddSlowdownScriptToWaypoints()
{
foreach (GameObject go in waypoints)
{
go.AddComponent<SlowDown>();
}
}
}
然后是SlowDown脚本
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
class SlowDown : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
Debug.Log("Object " + other.name + " entered " + name);
WayPoints.SetSpeed(WayPoints.moveSpeedSlowedWalk);
}
private void OnTriggerExit(Collider other)
{
Debug.Log("Object " + other.name + " exited " + name);
WayPoints.SetSpeed(WayPoints.moveSpeedWalk);
}
}
在ThirdPersonController脚本中我添加了这个
public void ChangeSpeed(float move)
{
m_MoveSpeedMultiplier = move;
}
现在我只使用移动速度变量而不是步行速度。所以我现在只使用此举,因为它是一个ThirdPersonController,而不是FirstPersonController。
但是当它以任何方式进入OnTriggerEnter时,它仍然没有放慢速度。
答案 0 :(得分:2)
我的想法是你可以检查2个检查点之间的距离,如果它是内联的,然后计算速度。
var distanceCheckpoint = Vector3.Distance(checpoint_1.position, checpoint_2.position);
var distance = Vector3.Distance(myTransform.position, target.transform.position);
var thresholdSpeed = distance / distanceCheckpoint * moveSpeed;
答案 1 :(得分:1)
假设玩家移动速度由浮动改变,并且您正在使用统一标准资产第3个第一人称控制器。您可以将其调整为自定义播放器控制器。无论如何,这个脚本要求你在编辑器中设置moveSpeedSetter,moveSpeedSlowedSetter和motorSetter。您可以将此脚本放在任何您喜欢的位置。
using UnityEngine;
public class WayPoints : MonoBehaviour
{
//setters for setting everything in Unity editor
public float moveSpeedSetter = 1f;
public float moveSpeedSlowedSetter = 0.5f;
public CharacterMotor motorSetter;
//static objects changeable via any script
public static float moveSpeed;
public static float moveSpeedSlowed;
public static CharacterMotor motor;
public static void SetSpeed(float speed)
{
motor.movement.maxForwardSpeed = speed;
}
private void Start()
{
moveSpeed = moveSpeedSetter;
moveSpeedSlowed = moveSpeedSlowedSetter;
motor = motorSetter;
motor.movement.maxForwardSpeed = moveSpeed;
}
}
之后在所有航点中创建空对象并为其添加触发器。然后将此脚本放在具有触发器的新创建的对象上。
using UnityEngine;
class SlowDown : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
Debug.Log("Object " +other.name+" entered "+ name);
WayPoints.SetSpeed(WayPoints.moveSpeedSlowed);
}
private void OnTriggerExit(Collider other)
{
Debug.Log("Object " + other.name + " exited " + name);
WayPoints.SetSpeed(WayPoints.moveSpeed);
}
}
---为下面的UNITY 5编辑---
因此,为了在Unity标准资产的gameObject FPSController中自由访问对象FirstPersonController的浮点WalkSpeed和RunSpeed,你必须修改它或者像你这样访问它们自己的方法。 (你可以把它放在FirstPersonController脚本中的任何地方)。
public void ChangeSpeed(float walk,float run)
{
m_WalkSpeed = walk;
m_RunSpeed = run;
}
这是移动速度控制的脚本
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
public class WayPoints : MonoBehaviour
{
//setters for setting everything in Unity editor
public float moveSpeedRunSetter = 10f;
public float moveSpeedSlowedRunSetter = 6f;
public float moveSpeedWalkSetter = 5f;
public float moveSpeedSlowedWalkSetter = 3f;
public FirstPersonController motorSetter;
//static objects changeable via any script
public static float moveSpeedRun;
public static float moveSpeedSlowedRun;
public static float moveSpeedWalk;
public static float moveSpeedSlowedWalk;
public static FirstPersonController motor;
public static void SetSpeed(float walk, float run)
{
motor.ChangeSpeed(walk, run);
}
private void Start()
{
moveSpeedWalk = moveSpeedWalkSetter;
moveSpeedSlowedWalk = moveSpeedSlowedWalkSetter;
moveSpeedRun = moveSpeedRunSetter;
moveSpeedSlowedRun = moveSpeedSlowedRunSetter;
motor = motorSetter;
motor.ChangeSpeed(moveSpeedWalk, moveSpeedRun);
}
}
这是航点的脚本
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
class SlowDown : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
Debug.Log("Object " +other.name+" entered "+ name);
WayPoints.SetSpeed(WayPoints.moveSpeedSlowedWalk, WayPoints.moveSpeedSlowedRun);
}
private void OnTriggerExit(Collider other)
{
Debug.Log("Object " + other.name + " exited " + name);
WayPoints.SetSpeed(WayPoints.moveSpeedWalk, WayPoints.moveSpeedRun);
}
}