2016-12-09 11 views
1

Я применил код к 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); 

      } 

     } 
    } 
+0

Является ли сценарий для каждого объекта? –

+0

Да, это один и тот же скрипт на каждом объекте –

+1

Вам нужен скрипт, который управляет «слотами» и устанавливает чашки в движение. Движение может выполняться самими чашками, но другой скрипт должен управлять слотами (в списке или массиве), чтобы все чашки знали, что они делают. Например, псевдокод может выглядеть как «чистые чашки из всех слотов и четкие цели из всех чашек», «случайные петли» и присваивание первому свободному слоту »,« расскажите каждой чашке, в какой позиции находится их цель ». В сценарии чашки вы можете просто проверить, установлено ли целевое свойство, если оно движется в эту позицию. – Charleh

ответ

1

Если вы добавляете этот сценарий для каждого из объектов, выполните следующее. Для этого требуется только один скрипт, и он добавляется к каждому из объектов 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, чтобы дать ему ту же точку обзора, что и моя (сначала сохраните сцену на всякий случай), затем запустите его.

+0

Просто попробовал это. Он отлично работает, спасибо! –

+0

Только для учебных целей, что вы добавили здесь. Это немного отличается от моего исходного кода, и я не знаком с такими вещами, как Mathf.Clamp или созданием статического списка ... это то же самое, что и создание массива? Все это кажется очень эффективным! –

+0

Статические объекты доступны в каждом объекте, и есть только один из них. Поэтому каждый из списков доступен для каждой чашки. но списки являются глобальными для всех. –

1

Я думаю, что вы должны сделать такой код для чашек:

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; 
    } 
} 

А потом глобальные геймобжекты шейкера с кодом вроде этого:

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]]); 
     } 
    } 
} 
+0

Спасибо! Я собираюсь попробовать это. Где/или какой объект я бы добавил в сценарий шейкера глобального игрового объекта? –

+0

Также, когда вы вводите «Чашки» с линией «Чашки [чашки]», я получаю сообщение об ошибке «Тип или имя пространства имен« Чашки »не могут быть найдены. Вам не хватает директивы использования или сборка? " –

+0

Николь сменить Кубки на тесты –