InstantiateObjects Я создаю объекты в случайных позициях, случайный масштаб, случайное вращение, а также случайную высоту.
Этот скрипт прикреплен к имени GameObject. InstantiateObjects Objects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InstantiateObjects : MonoBehaviour
{
public GameObject prefab;
public Terrain terrain;
public float yOffset = 0.5f;
[Range(10, 1000)]
public int objectsAmount = 20;
public bool randomScale = false;
public bool randomRotation = false;
[Range(1, 100)]
public float spinSpeed = 50;
public bool spinPbjects = false;
public bool parent = true;
public string parentName;
public bool addNewAtStart = false;
public Vector3 RandScaleMin;
public Vector3 RandScaleMax;
[Range(0, 360)]
public float randomRotationX;
[Range(0, 360)]
public float randomRotationY;
[Range(0, 360)]
public float randomRotationZ;
private float terrainWidth;
private float terrainLength;
private float xTerrainPos;
private float zTerrainPos;
private int oldAmount;
private GameObject objInstance;
void Start()
{
//Get terrain size
terrainWidth = terrain.terrainData.size.x;
terrainLength = terrain.terrainData.size.z;
//Get terrain position
xTerrainPos = terrain.transform.position.x;
zTerrainPos = terrain.transform.position.z;
oldAmount = objectsAmount;
generateObjectOnTerrain();
}
void generateObjectOnTerrain()
{
for (int i = 0; i < objectsAmount; i++)
{
//Generate random x,z,y position on the terrain
float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
float randY = UnityEngine.Random.Range(0, 100);
float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
var randScaleX = Random.Range(RandScaleMin.x, RandScaleMax.x);
var randScaleY = Random.Range(RandScaleMin.y, RandScaleMax.y);
var randScaleZ = Random.Range(RandScaleMin.z, RandScaleMax.z);
var randVector3 = new Vector3(randScaleX, randScaleY, randScaleZ);
var randRotX = Random.Range(0, randomRotationX);
var randRotY = Random.Range(0, randomRotationY);
var randRotZ = Random.Range(0, randomRotationZ);
var randRotation = Quaternion.Euler(randRotX, randRotY, randRotZ);
//Apply Offset if needed
yVal = yVal + yOffset;
objInstance = (GameObject)Instantiate(prefab, new Vector3(randX, /*yVal*/ randY, randZ), Quaternion.identity);
objInstance.tag = "Target";
if (randomScale == true)
{
objInstance.transform.localScale = randVector3;//new Vector3(randScaleX, randScaleY, randScaleZ);
}
if (randomRotation == true)
{
objInstance.transform.rotation = randRotation;
}
if (parent)
{
if (parentName != null && parentName != "")
{
GameObject parent = GameObject.Find(parentName);
objInstance.transform.parent = parent.transform;
}
else
{
objInstance.transform.parent = gameObject.transform;
}
}
}
}
}
На камереназвание Fly Camera У меня есть два прикрепленных сценария:
Fly To Over Terrain:
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;
}
}
И Patrol Over Terrain:
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;
}
}
}
Основная проблема, которая меня смущаетявляется переменной требуемой высоты в скрипте Fly To Over Terrain.В скрипте Fly To Over Terrain значение требуемого значения Height равно 10, в сценарии Patrol Over Terrain в классе PatrolData значение требуемого значения Height также равно 10, но затем в нижней части метода GeneratePatrolPoints значение требуемого значения высоты равно 20.
Таким образом, на самом деле не имеет значения, какое значение я установил требуемой высотой в инспекторе сценария «Полет над землей», например, если я установлю его на 100 после первой цели, она изменится на 20, а затем на Fly Cameraне летать к следующей цели.
И с первым скриптом InstantiateObjects, если я не генерирую объекты со случайной высотой, так что, может быть, каким-то образом я смогу получить высоту объектов и установить ее уже на требуемый высоту, так как всеобъекты генерируются с одинаковой высотой.
Но если я создаю объекты со случайной высотой?например, между 0 и 100. Что мне делать с желаемой высотой тогда?Чтобы установить его на максимальную высоту 100?Чтобы получить переменную высоты из сценария InstantiateObjects и установить для него требуемыйВысота?
Тем не менее, требуемыйВысота будет все время сбрасываться на 20.
Так что я немного запутался, как интегрироватьмежду сценариями и значениями высоты.
Может быть, все это должно каким-то образом автоматически включаться при каждой следующей высоте цели и каждый раз задавать Желаемую высоту для этого значения высоты каждой цели?