在 Unity 中使用矢量数学生成游戏对象?

问题描述

我正在 Unity 中开发一个视频游戏,我在设计其中一个关卡时遇到了一个向量数学问题。我想生成两个平行于屏幕对角线相互连接的矩形块:

wo rectangular blocks attached to each other in tangent to the diagonal

红色方块需要相对于黄色方块的位置生成,而黄色方块需要以这样一种方式生成,如果我将它移回屏幕的对角线,它总是会以位于屏幕范围内的屏幕对角线上的位置,例如第二个示例中红线上的某处:

Dioganal line tangent to each position the yellow bar can have

我想这样做也是为了确保每当我告诉黄线和红线向中心移动的同时,当它们位于屏幕中心时,它们将始终沿着该线结束

Movement of the yellow and red bar. The yellow bar needs to always end up along the red line in the middle when moving towards the centre

。我试图确保屏幕的两条对角线以及矩形的四个边中的每条边都会发生这种情况。但是由于某种原因,我的数学似乎不起作用。每当条形生成时,它们就会到处生成

How they spawn now

这是我当前编写的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;

public class BallSpawnerControl3 : MonoBehavIoUr
{
    int index = 1;
    public Transform[] spawnPointsLevel3;
    int randomSpawnPoint,Interact;
    ObjectPooler objectPooler;
    public static bool Spawn;
    public static int Level3Trans = 1;
    private float RandomSpawn;
    private float Y_intercept;
    float PointBarVectorLength;
    float PointBarLength;
    Quaternion rot;
    private Vector2 Ylength;
    private Vector2 Xlength;
    Vector2 PointBarVectorConv;
    Quaternion PointBarVerticalRot;
    Quaternion PointBarDiagonalLeftRot;
    Quaternion PointBarDiagonalRightRot;
    Quaternion RedBarVerticalRot;
    Quaternion RedBarDiagonalLeftRot;
    Quaternion RedBarDiagonalRightRot;
    Quaternion QuaResult;

    public void Start()
    {
        objectPooler = ObjectPooler.Instance;
        
        GameObject PointBar = (GameObject) Resources.Load("PointBar Horizontal");
        GameObject PointBarVertical = (GameObject) Resources.Load("PointBar Vertical");
        GameObject PointBarDiagonalLeft = (GameObject)Resources.Load("PointBar Diagonal Left");
        GameObject PointBarDiagonalRight = (GameObject)Resources.Load("PointBar Diagonal Right");
        GameObject RedBarVertical = (GameObject)Resources.Load("Red Bar Vertical");
        GameObject RedBarDiagonalLeft = (GameObject)Resources.Load("Red Bar Diagonal Left");
        GameObject RedBarDiagonalRight = (GameObject)Resources.Load("Red Bar Diagonal Right");
        PointBarVerticalRot = PointBarVertical.GetComponent<Transform>().rotation;
        PointBarDiagonalLeftRot = PointBarDiagonalLeft.GetComponent<Transform>().rotation;
        PointBarDiagonalRightRot = PointBarDiagonalRight.GetComponent<Transform>().rotation;
        RedBarVerticalRot = RedBarVertical.GetComponent<Transform>().rotation;
        RedBarDiagonalLeftRot = RedBarDiagonalLeft.GetComponent<Transform>().rotation;
        RedBarDiagonalRightRot = RedBarDiagonalRight.GetComponent<Transform>().rotation;
        PointBarVectorLength = PointBar.GetComponent<SpriteRenderer>().bounds.size.x;
        PointBarVectorConv = Camera.main.WorldToViewportPoint(new Vector2(PointBarVectorLength,0f));

        rot = new Quaternion(0,180,0);
        Spawn = true;
       
        InvokeRepeating("SpawnAInteract",0f,1f);
    }

    void SpawnAInteract()
    {

        // Scene scene = SceneManager.GetActiveScene();


        if (Spawn && scoreScript.scoreValue > 11 && SceneManager.GetActiveScene().name == "Level 3")
        {
            if (scoreScript.scoreValue > 4 && Level3Trans == 1)
            {
                StartCoroutine(LevelTransition3());
            }

            else
            {
                randomSpawnPoint = UnityEngine.Random.Range(0,spawnPointsLevel3.Length);
                Interact = 1;

                if (randomSpawnPoint == 0 || randomSpawnPoint == 4)
                {
                    RandomSpawn = UnityEngine.Random.Range(-0.5f,0.5f - PointBarVectorConv.x);

                    if (index % 5 != 0)
                    {
                        objectPooler.SpawnFromPool("PointBar Horizontal",spawnPointsLevel3[randomSpawnPoint].position + Camera.main.ViewportToWorldPoint(new Vector3(RandomSpawn,0)),Quaternion.identity);
                        Debug.Log("PointBar Horizontal");
                    }

                    QuaResult = transform.rotation * rot;

                    objectPooler.SpawnFromPool("Red Bar Horizontal",spawnPointsLevel3[randomSpawnPoint].position + Camera.main.ViewportToWorldPoint(new Vector3(RandomSpawn + PointBarVectorLength,Quaternion.identity);
                    objectPooler.SpawnFromPool("Red Bar Horizontal",QuaResult);
                    Debug.Log("PointBar Diagonal Left");
                }

                else if (randomSpawnPoint == 1 || randomSpawnPoint == 5)
                {
                    if (randomSpawnPoint == 1)
                    {
                        RandomSpawn = UnityEngine.Random.Range(0.7f,1.8f);
                        Y_intercept = 3.96f;

                    }

                    if (randomSpawnPoint == 5)
                    {
                        RandomSpawn = UnityEngine.Random.Range(-0.8f,0.3f);
                        Y_intercept = -1.085f;
                    }


                    int Gradient = -1;

                    float PointBarYPosition = DiagonalRight(RandomSpawn,Y_intercept);

                    Vector2 PointBarPosition = Camera.main.ViewportToWorldPoint(new Vector3(RandomSpawn,PointBarYPosition,0));

                    if (index % 5 != 0)
                    {
                        objectPooler.SpawnFromPool("PointBar Diagonal Left",PointBarPosition,PointBarDiagonalLeftRot);
                        Debug.Log("PointBar Diagonal Left");
                    }

                    QuaResult = RedBarDiagonalLeftRot * rot;

                    objectPooler.SpawnFromPool("Red Bar Diagonal Left",Camera.main.ViewportToWorldPoint(new Vector3(RedBarDiagonalRightX(RandomSpawn,PointBarVectorLength,Gradient),RedBarDiagonalRightY(PointBarVectorLength,RedBarDiagonalLeftRot);//Adapt this and the next line in order to spawn to red bars attached to the yellow one
                    objectPooler.SpawnFromPool("Red Bar Diagonal Left",QuaResult);
                    Debug.Log("Red Bar Diagonal Left");
                }

                else if (randomSpawnPoint == 2 || randomSpawnPoint == 6) // |□|
                {
                    RandomSpawn = UnityEngine.Random.Range(-0.5f,0.5f - PointBarVectorConv.x);

                    if (index % 5 != 0)
                    {
                        objectPooler.SpawnFromPool("PointBar Vertical",spawnPointsLevel3[randomSpawnPoint].position + Camera.main.ViewportToWorldPoint(new Vector3(0,RandomSpawn,PointBarVerticalRot);
                        Debug.Log("Pointbar Vertical");
                    }

                    QuaResult = RedBarVerticalRot * rot;

                    objectPooler.SpawnFromPool("Red Bar Vertical",RandomSpawn + PointBarVectorLength,RedBarVerticalRot);
                    objectPooler.SpawnFromPool("Red Bar Vertical",QuaResult);
                    Debug.Log("Red Bar Vertical");
                }

                else if (randomSpawnPoint == 3 || randomSpawnPoint == 7)  // /□/
                {
                    if (randomSpawnPoint == 3)
                    {
                        RandomSpawn = UnityEngine.Random.Range(0.7f,1.8f);
                        Y_intercept = -2.96f;
                    }

                    if (randomSpawnPoint == 7)
                    {
                        RandomSpawn = UnityEngine.Random.Range(-0.8f,0.3f);
                        Y_intercept = 2.085f;
                    }

                    int Gradient = 1;

                    float PointBarYPosition = DiagonalLeft(RandomSpawn,0));// main might have to be changed too the camera active in Level 3

                    if (index % 5 != 0)
                    {
                        objectPooler.SpawnFromPool("PointBar Diagonal Right",PointBarDiagonalRightRot);
                        Debug.Log("PointBar Diagonal Right");
                    }

                    QuaResult = RedBarDiagonalRightRot * rot;

                    objectPooler.SpawnFromPool("Red Bar Diagonal Right",RedBarDiagonalRightRot);// Adapt this and the next line in order to spawn to red bars attached to the yellow one
                    objectPooler.SpawnFromPool("Red Bar Diagonal Right",QuaResult);
                    Debug.Log("Red Bar Diagonal Right");
                }


                index++;

            }

        }

    }

    private float DiagonalRight(float RandomSpawn,float Y_intercept) // Y = -1X + 14.09 ==> Formula
    {
        float Yposition = -RandomSpawn + Y_intercept;
        return Yposition;

    }

    private float RedBarDiagonalRightX(float RandomSpawn,float PointBarVectorLength,int Gradient) // Y = -1X + 14.09 ==> Formula
    {
        float RedXPosition = RandomSpawn + PointBarVectorLength / (float)(Math.Sqrt(1 + Math.Pow(Gradient,2)));
        return RedXPosition;

    }

    private float RedBarDiagonalRightY(float PointBarVectorLength,float PointBarYPosition,int Gradient) // Y = -1X + 14.09 ==> Formula
    {
        float RedYPosition = PointBarYPosition + (Gradient * PointBarVectorLength) / (float)(Math.Sqrt(1 + Math.Pow(Gradient,2)));
        return RedYPosition;

    }

    
    private float DiagonalLeft(float RandomSpawn,float Y_intercept) // Y = -1X + 14.09 ==> Formula
    {
        float Yposition = RandomSpawn - Y_intercept;
        return Yposition;

    }

  

    private IEnumerator LevelTransition3()
    {

        yield return new WaitForSeconds(1f);
        Level3Trans++;
        Debug.Log("Level Trans :" + Level3Trans);

    }


}

我想注意

1)randomSpawnPoint == Spawnpoint (1+ randomSpawnPoint) 用于如下图所示的位置:

positions of Spawnpoints

  1. 我通过将屏幕大小与场景中对象的大小进行比较,手动计算了大部分浮点值。

我现在的问题是问任何在 Unity 中有经验的人,如果没有一种简单的方法可以完成我似乎没有掌握的事情。因为考虑到多年来创造的所有游戏,我似乎正在为我认为应该相对容易做的事情做很多计算。或者,如果我的计算明显错误,如果有人可以帮助我朝着正确的方向发展,我会很感激吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)