You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

254 lines
7.6 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class CastleAnimator : MonoBehaviour {
public float WaitAtStart = 2;
public float MoveSpeed = 30;
public float MaxWaitTime = 5;
[SerializeField]
public AnimationCurve SpeedCurve;
public float BridgeSpeed = 30;
public float maxBridgeWaitTime = 0.5f;
[SerializeField]
public AnimationCurve ScaleCurve;
[System.Serializable]
public struct Base {
public GameObject gameObject;
public Bounds BaseBound;
public Tower tower;
}
[System.Serializable]
public struct Tower {
public Vector3 originalPos;
public GameObject gameObject;
public List<GameObject> TowerPieces;
public GameObject[] ScalePoints;
}
[HideInInspector]
public List<Base> Bases = new List<Base>();
public enum ScaleDirection {PositiveX, PositiveZ, NegativeX, NegativeZ }
public void Start()
{
if (MoveSpeed == 0) {
Debug.LogWarning("Tower Movement set to 0");
return;
}
foreach(Base Base in Bases) {
StartCoroutine(MoveTower(Base.tower, MoveSpeed, MaxWaitTime));
}
}
private IEnumerator MoveTower(Tower tower, float moveSpeed, float startRandomizer)
{
foreach (GameObject scalePoint in tower.ScalePoints) {
scalePoint.SetActive(false);
scalePoint.transform.localScale = Vector3.zero;
}
Vector3 endPos = tower.gameObject.transform.position;
tower.gameObject.transform.localPosition = Vector3.zero;
Vector3 startPos = tower.gameObject.transform.position;
float elapsedTime = 0;
float randomWait = Random.Range(0, startRandomizer);
float animationTime = (Vector3.Distance(endPos, startPos) / moveSpeed);
yield return new WaitForSeconds(randomWait + WaitAtStart);
while (elapsedTime < animationTime) {
float curvePercent = SpeedCurve.Evaluate((elapsedTime / animationTime));
tower.gameObject.transform.position = UnclampedLerp(startPos, endPos, curvePercent);
elapsedTime += Time.deltaTime;
yield return new WaitForEndOfFrame();
}
tower.gameObject.transform.position = endPos;
StartCoroutine(scaleBridge(tower.ScalePoints[0], ScaleDirection.PositiveX, BridgeSpeed,maxBridgeWaitTime));
StartCoroutine(scaleBridge(tower.ScalePoints[1], ScaleDirection.PositiveZ, BridgeSpeed,maxBridgeWaitTime));
StartCoroutine(scaleBridge(tower.ScalePoints[2], ScaleDirection.NegativeX, BridgeSpeed,maxBridgeWaitTime));
StartCoroutine(scaleBridge(tower.ScalePoints[3], ScaleDirection.NegativeZ, BridgeSpeed,maxBridgeWaitTime));
}
private IEnumerator scaleBridge(GameObject scalePoint, ScaleDirection direction, float scaleSpeed, float startRandomizer)
{
float randomWait = Random.Range(0, startRandomizer);
yield return new WaitForSeconds(randomWait);
scalePoint.SetActive(true);
Vector3 scaleVector = Vector3.zero;
if (direction == ScaleDirection.NegativeX || direction == ScaleDirection.PositiveX) {
scaleVector = Vector3.right;
scalePoint.transform.localScale = new Vector3(0, 1, 1);
} else {
scaleVector = Vector3.forward;
scalePoint.transform.localScale = new Vector3(1, 1, 0);
}
Vector3 startScale = scalePoint.transform.localScale;
float elapsedTime = 0;
float animationTime = 10 / scaleSpeed;
while (elapsedTime < animationTime) {
float curvePercent = ScaleCurve.Evaluate((elapsedTime / animationTime));
scalePoint.gameObject.transform.localScale = UnclampedLerp(startScale, Vector3.one, curvePercent);
elapsedTime += Time.deltaTime;
yield return new WaitForEndOfFrame();
}
scalePoint.transform.localScale = Vector3.one;
}
public static Vector3 UnclampedLerp(Vector3 a, Vector3 b, float t)
{
return t * b + (1 - t) * a;
}
private Bounds getWorldBounds(GameObject input)
{
Bounds retVal = new Bounds(input.transform.position, Vector3.zero);
foreach (Renderer renderer in input.GetComponentsInChildren<Renderer>()) {
retVal.Encapsulate(renderer.bounds);
}
return retVal;
}
private void MoveParent(GameObject input, Vector3 moveTo)
{
Vector3 movement = moveTo - input.transform.position;
input.transform.position = moveTo;
foreach (Transform child in input.transform) {
child.position -= movement;
}
}
#if UNITY_EDITOR
public void AddBase(Transform input)
{
Base newBase = new Base();
GameObject Base = new GameObject();
Undo.RegisterCreatedObjectUndo(Base, "Created Base");
Base.transform.position = getWorldBounds(input.gameObject).center;
Base.transform.parent = transform;
Base.name = "Base" + Bases.Count;
Undo.SetTransformParent(input.transform, Base.transform, "Created Base");
//newBaseObject.parent = Base.transform;
newBase.gameObject = Base;
Undo.RecordObject(this, "Created Base");
GameObject towerHolder = new GameObject();
towerHolder.transform.parent = Base.transform;
towerHolder.transform.localPosition = Vector3.zero;
towerHolder.name = "Tower Holder" + Bases.Count;
newBase.tower = new Tower();
newBase.tower.gameObject = towerHolder;
newBase.tower.TowerPieces = new List<GameObject>();
newBase.tower.ScalePoints = new GameObject[4];
for (int i = 0; i < 4; i++) {
newBase.tower.ScalePoints[i] = new GameObject();
newBase.tower.ScalePoints[i].transform.parent = Base.transform;
newBase.tower.ScalePoints[i].transform.localPosition = Vector3.zero;
newBase.tower.ScalePoints[i].name = "ScalePoint" + Bases.Count + ", " + i;
}
Bases.Add(newBase);
}
public void AddTower(Base selectedBase, Transform[] input)
{
Undo.RecordObject(this, "Added Tower");
foreach (Transform towerObject in input) {
if (towerObject == selectedBase.gameObject.transform)
continue;
if (selectedBase.tower.TowerPieces.Contains(towerObject.gameObject))
continue;
selectedBase.tower.TowerPieces.Add(towerObject.gameObject);
Undo.SetTransformParent(towerObject.transform, selectedBase.tower.gameObject.transform, "Added Tower");
}
Undo.RecordObject(selectedBase.tower.gameObject, "Added Tower");
MoveParent(selectedBase.tower.gameObject, selectedBase.gameObject.transform.position + ((getWorldBounds(selectedBase.tower.gameObject).size.y) * Vector3.up));
selectedBase.tower.originalPos = selectedBase.tower.gameObject.transform.position;
}
public void AddBridge(Base selectedBase,ScaleDirection direction, Transform[] input)
{
foreach (Transform bridgeObject in input) {
if (bridgeObject == selectedBase.gameObject)
continue;
if (selectedBase.tower.TowerPieces.Contains(bridgeObject.gameObject))
continue;
Undo.SetTransformParent(bridgeObject.transform, selectedBase.tower.ScalePoints[(int)direction].transform, "Added Bridge");
}
}
public string[] GetBaseNames()
{
string[] retVal = new string[Bases.Count];
for (int i = 0; i < retVal.Length; i++) {
retVal[i] = "Tower" + i;
}
return retVal;
}
#endif
}