Как я могу преобразовать 3 объекта, чтобы поменять их местами, но убедиться, что они не перемещаются в положение, в которое уже собирается объект?
Я применил код к 3 объектам. Пока этот код переключает три чашки так, чтобы они поменялись местами. Код получает начальную позицию чашки, а затем конечную позицию каждой чашки. Все 3 конечные позиции на самом деле являются начальными позициями других чашек, так как я хочу, чтобы они менялись на те же точные позиции, что и другие чашки. Функция обновления делает так, что если конечная позиция чашки (которая выбрана случайным образом) НЕ равна ее начальной позиции, она будет перемещаться в одну из двух других точек, которые не были ее начальной позицией, случайным образом.
У меня проблемы с выяснением пары вещей, и я попробовал несколько вещей, но я не думаю, что я правильно понимаю код. Я бы хотел:
Заставьте чашки беспорядочно перемещаться в их новое место, но не перемещайте чашку в то место, куда уже перемещается другая чашка. (В настоящее время при воспроизведении анимации 2 чашки потенциально перемещаются в одно и то же место из 3-х точек).
Я просто не уверен, в каком направлении идти. Мне также хотелось бы, чтобы эта анимация продолжала играть и чтобы чашки постоянно менялись местами. Было бы полезно получить точку в направлении выяснения этого также.
Вот что я хочу, чтобы конечный результат был похож: http://i249.photobucket.com/albums/gg240/OldNewby4507/shell-game-animated.gif
Заранее спасибо.
using UnityEngine;
using System.Collections;
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{
private Vector3 startPos;
private float lerp = 0, duration = 1;
public Vector3[] endPos = new Vector3[3];
int index;
Vector3 theNewPos;
void Start ()
{
startPos = transform.position;
endPos [0] = GameObject.Find ("object1").transform.position;
endPos [1] = GameObject.Find ("object2").transform.position;
endPos [2] = GameObject.Find ("object3").transform.position;
index = Random.Range (0, endPos.Length);
theNewPos = endPos[index];
}
void Update() {
if (theNewPos != startPos) {
lerp += Time.deltaTime / duration;
transform.position = Vector3.Lerp (startPos, theNewPos, lerp);
}
}
}
2 ответа
Если вы добавляете этот скрипт к каждому из объектов, сделайте следующее. Для этого требуется только один скрипт, и он добавляется к каждому из cup
объекты.
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
public class rotateCups : MonoBehaviour
{
private float lerp = 0f, speed = 5f;
static List<Vector3> listOfCupPositions, shuffleList;
Vector3 theNewPos, startPos;
readonly int shuffleSpeed = 100;
int shuffle = 0;
void Start()
{
if (null == listOfCupPositions)
{
// These lists are global to each cup
listOfCupPositions = new List<Vector3>();
shuffleList = new List<Vector3>();
}
theNewPos = startPos = transform.position;
listOfCupPositions.Add(theNewPos); // Add this cup to the main list
}
void Update()
{
if (startPos != theNewPos)
{
lerp += Time.deltaTime * speed;
lerp = Mathf.Clamp(lerp, 0f, 1f); // keep lerp between the values 0..1
transform.position = Vector3.Lerp(startPos, theNewPos, lerp);
if (lerp >= 1f)
{
startPos = theNewPos;
lerp = 0f;
}
}
}
void LateUpdate()
{
if (--shuffle <= 0)
{
// Shuffle the cups
shuffle = shuffleSpeed;
if (0 == shuffleList.Count)
shuffleList = listOfCupPositions.ToList(); // refresh shuffle positions
// Loop until we get a position this cup isn't,
// or unless there's only one spot left in shuffle list,
// use it (ie don't move this cup this round)
int index;
do
{
index = Random.Range(0, shuffleList.Count);
} while (startPos == shuffleList[index] && shuffleList.Count > 1);
// give this cup a new position
theNewPos = shuffleList[index];
shuffleList.RemoveAt(index); // remove position from shuffle list so it isn't duplicated to another cup
}
}
}
Это забавная мелочь, чтобы посмотреть в действии. Чтобы проверить это, я добавил куб, капсулу и сферу, переместил их в 3 отдельных места, добавил сценарий к каждому, а затем с выбранной камерой сделал Ctrl+ Shift+F, чтобы дать ему ту же точку обзора, что и мой окно редактора (сначала сохраните сцену на всякий случай), затем запустите ее.
Я думаю, что вы должны сделать такой код для своих чашек:
using UnityEngine;
public class Cup : MonoBehaviour
{
public Vector3 startPos;
private float lerp = 0, duration = 1;
Vector3 theNewPos;
void Awake()
{
startPos = transform.position;
theNewPos = transform.position;
}
void Start()
{
}
void Update()
{
float thresholdSqr = 0.01f;
if ((theNewPos - transform.position).sqrMagnitude > thresholdSqr)
{
lerp += Time.deltaTime / duration;
transform.position = Vector3.Lerp(startPos, theNewPos, lerp);
}
else
{
transform.position = theNewPos;
startPos = transform.position;
}
}
public void MoveToSpot(Vector3 pos)
{
theNewPos = pos;
lerp = 0f;
}
}
И затем глобальный шейкер Gameobject с кодом, подобным этому:
using UnityEngine;
using System.Linq;
public class Shaker : MonoBehaviour
{
Cup[] cups;
Vector3[] spots;
void Start()
{
cups = GameObject.FindObjectsOfType<Cup>();
spots = cups.Select(c => c.startPos).ToArray();
}
void Update()
{
}
void Shake()
{
int[] newIndices = Enumerable.Repeat(-1, cups.Length).ToArray();
for (int i = 0; i < cups.Length; i++) //there could be another random sort algorithm, for example to make that every cup would move to another spot.
{
int free = cups.Length - i;
int j = Random.Range(0, free);
for (int k = j; k < cups.Length; k++)
{
if (newIndices[k] == -1)
{
newIndices[k] = i;
break;
}
}
}
for (int i = 0; i < cups.Length; i++)
{
cups[i].MoveToSpot(spots[newIndices[i]]);
}
}
}