Как я могу преобразовать 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]]);
        }
    }
}
Другие вопросы по тегам