dzrone3488 | Дата: Среда, 13 Июля 2016, 03:11 | Сообщение # 1 |
участник
Сейчас нет на сайте
| Настал час сделать, что-нибудь современное. Решил, что многие начинали со слендеров, майнкравтов, сурвиволов, и.т.д, а я решил заняться небольшой геометрической игрой, где надо будет играть за фигуры, в конце концов думаю некоторые знают какой я разработчик моделей. Ну вот придумал как будет двигаться мой кубик (пока что только кубик). Но вот проблема, не хочу совершать ошибок многих, если я делаю игру, то должен знать в точности как работает каждая строчка и что делает, как с программной точки зрения, так и с математической(Исключение: Кватернион). Вот ссылка на видео, там показано как японец демонстрирует движение кубика в точности такое-же какое я хотел сделать в своём проекте. Ну начнём с того, что японского я не знаю, а Гугл пока что не способен переводить текст такого содержания, так как такой текст должен быть переведён в точности. Думаю на этом пункте можно и закончить, но ладно... Во вторых я с математической стороны кода, ну... нечего не понимаю. Прошу объяснить! Как это работает? Думаю люди способные увидеть этот алгоритм действий смогут мне помочь! В описании видео, как раз есть ссылка на статью, где описано как делается такая система передвижения, но... На японском... Жду ваших ответов! Буду заранее очень благодарен!
http://piromayo.xyz/2016/04/27/colorful-dice-サイコロを転がすスクリプト/
Код using System.Collections; public class move2 : MonoBehaviour { public float rotationPeriod = 0.3f; // 隣に移動するのにかかる時間 public float sideLength = 1f; // Cubeの辺の長さ bool isRotate = false; // Cubeが回転中かどうかを検出するフラグ float directionX = 0; // 回転方向フラグ float directionZ = 0; // 回転方向フラグ Vector3 startPos; // 回転前のCubeの位置 float rotationTime = 0; // 回転中の時間経過 float radius; // 重心の軌道半径 Quaternion fromRotation; // 回転前のCubeのクォータニオン Quaternion toRotation; // 回転後のCubeのクォータニオン // Use this for initialization void Start () { // 重心の回転軌道半径を計算 radius = sideLength * Mathf.Sqrt (2f) / 2f; } // Update is called once per frame void Update () { float x = 0; float y = 0; // キー入力を拾う。 x = Input.GetAxisRaw ("Horizontal"); if (x == 0) { y = Input.GetAxisRaw ("Vertical"); } // キー入力がある かつ Cubeが回転中でない場合、Cubeを回転する。 if ((x != 0 || y != 0) && !isRotate) { directionX = y; // 回転方向セット (x,yどちらかは必ず0) directionZ = x; // 回転方向セット (x,yどちらかは必ず0) startPos = transform.position; // 回転前の座標を保持 fromRotation = transform.rotation; // 回転前のクォータニオンを保持 transform.Rotate (directionZ * 90, 0, directionX * 90, Space.World); // 回転方向に90度回転させる toRotation = transform.rotation; // 回転後のクォータニオンを保持 transform.rotation = fromRotation; // CubeのRotationを回転前に戻す。(transformのシャローコピーとかできないんだろうか…。) rotationTime = 0; // 回転中の経過時間を0に。 isRotate = true; // 回転中フラグをたてる。 } } void FixedUpdate() { if (isRotate) { rotationTime += Time.fixedDeltaTime; // 経過時間を増やす float ratio = Mathf.Lerp(0, 1, rotationTime / rotationPeriod); // 回転の時間に対する今の経過時間の割合 // 移動 float thetaRad = Mathf.Lerp(0, Mathf.PI / 2f, ratio); // 回転角をラジアンで。 float distanceX = -directionX * radius * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + thetaRad)); // X軸の移動距離。 -の符号はキーと移動の向きを合わせるため。 float distanceY = radius * (Mathf.Sin(45f * Mathf.Deg2Rad + thetaRad) - Mathf.Sin (45f * Mathf.Deg2Rad)); // Y軸の移動距離 float distanceZ = directionZ * radius * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + thetaRad)); // Z軸の移動距離 transform.position = new Vector3(startPos.x + distanceX, startPos.y + distanceY, startPos.z + distanceZ); // 現在の位置をセット // 回転 transform.rotation = Quaternion.Lerp(fromRotation, toRotation, ratio); // Quaternion.Lerpで現在の回転角をセット(なんて便利な関数) // 移動・回転終了時に各パラメータを初期化。isRotateフラグを下ろす。 if (ratio == 1) { isRotate = false; directionX = 0; directionZ = 0; rotationTime = 0; } } } }
Я делаю игры, а вы в них играете! :) Моя группа по созданию игр - www.vk.com/dzrone
|
|
| |
shustr1k76 | Дата: Пятница, 15 Июля 2016, 17:38 | Сообщение # 2 |
почетный гость
Сейчас нет на сайте
| давай я попробую, а там кто нибудь исправить и дополнить правильность))
Цитата dzrone3488 ( ) using System.Collections;
public class move2 : MonoBehaviour {
public float rotationPeriod = 0.3f; // период поворота public float sideLength = 1f; // длина стороны куба
bool isRotate = false; // булевая связаная с повортом float directionX = 0; // направление по х при равненая 0 float directionZ = 0; //направление по z при равненая 0
Vector3 startPos; // стартовая позиция в трехмерном пространстве float rotationTime = 0; // время поворота float radius; // радиус Quaternion fromRotation; // угол поворота от Quaternion toRotation; // угол поворота куда
// Use this for initialization void Start () {
// математическая функция Mathf по множеная на длину стороны куба как ты помнишь выше)) это радиус radius = sideLength * Mathf.Sqrt (2f) / 2f;
}
// Update is called once per frame void Update () {
float x = 0; float y = 0;
// движение по оси х, если равен == 0 то делаем движение по оси у x = Input.GetAxisRaw ("Horizontal"); if (x == 0) { y = Input.GetAxisRaw ("Vertical"); }
// если х не равен 0 или у не равен 0 и бул является отрицанием (false) if ((x != 0 || y != 0) && !isRotate) { directionX = y; // направление по х = у directionZ = x; // направление по у = х startPos = transform.position; // стартовая позиция при равнена к преобразованию позиции fromRotation = transform.rotation; // от куда transform.Rotate (directionZ * 90, 0, directionX * 90, Space.World); // преобразование поворота toRotation = transform.rotation; // куда поворачиваемся опять же с преобразованием transform.rotation = fromRotation; // тут что то связаное с поворотом куба rotationTime = 0; // время поворота isRotate = true; // бул равен правде } }
void FixedUpdate() {
if (isRotate) {
rotationTime += Time.fixedDeltaTime; // к времени поворота прибовляется от выбранной частоты обновления физики float ratio = Mathf.Lerp(0, 1, rotationTime / rotationPeriod); // 回転の時間に対する今の経過時間の割合
// 移動 float thetaRad = Mathf.Lerp(0, Mathf.PI / 2f, ratio); // 回転角をラジアンで。 float distanceX = -directionX * radius * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + thetaRad)); //находим дистанцию х float distanceY = radius * (Mathf.Sin(45f * Mathf.Deg2Rad + thetaRad) - Mathf.Sin (45f * Mathf.Deg2Rad)); //находим дистанцию y float distanceZ = directionZ * radius * (Mathf.Cos (45f * Mathf.Deg2Rad) - Mathf.Cos (45f * Mathf.Deg2Rad + thetaRad)); // находим дистанцию z transform.position = new Vector3(startPos.x + distanceX, startPos.y + distanceY, startPos.z + distanceZ); // устанавливаем новую позицию в трехмерном пространстве
// 回転 transform.rotation = Quaternion.Lerp(fromRotation, toRotation, ratio); // Quaternion.Lerpで現在の回転角をセット(なんて便利な関数)
// сдесь идет речь, если ратио равен 1 то булевая isRotate - не правда, направление по осям х и у при равневаем 0 и время поворота тоже if (ratio == 1) { isRotate = false; directionX = 0; directionZ = 0; rotationTime = 0; } } } }
большие дядьки помогите)) и исправьте меня! полюбому где то описал не правильно и коряво, да и к тому же не все) сам учусь
а так все переменные дают тебе понять, что есть что))) дядьки не ругайтесь только!
Сообщение отредактировал shustr1k76 - Пятница, 15 Июля 2016, 17:48 |
|
| |
falcoware | Дата: Пятница, 15 Июля 2016, 18:07 | Сообщение # 3 |
старожил
Сейчас нет на сайте
| dzrone3488, все просто - вращают кубик на 90 градусов и меняю позицию благодаря тригонометрии. Учи матчать!
|
|
| |