控制Ray

时间:2017-12-11 10:11:59

标签: c# unity3d math

我是Unity的新手,有一个我无法弄清楚的问题。我希望对象在距离FPS播放器20的距离内随机生成。你可以说对象需要以玩家为中心在半球的表面上产生。但是:并非所有领域都可以使用。 “最高”部分太高,无法生成物体,因此基本上它是一个顶部被切掉的球体。

我尝试了什么:

thePosition = Random.onUnitSphere * 20 + object2.transform.position;

显然,这考虑了整个球体(应该只有半个球体),并没有考虑到“切断”部分。

所以我想:我基本上想制作可以在地面上旋转的光线(因此最大角度为360°),并且可以上下移动,最大角度为90°。可以把它想象成一个可以转动(转动)并以一定角度向上/向下转动的佳能。这是我的意思的图像:sketch

所以我尝试了:

Vector3 raydirection = new Vector3 (1f, 1f, 0);
     
raydirection = Quaternion.Euler (45, 0, 0) * raydirection;
Ray ray = new Ray (player.transform.position, raydirection);
    
thePosition = ray.GetPoint (20);

但这不允许我分别控制转角(角度1)和“上下”角度(角度2)。

所以我的问题是:我怎样才能让它能够控制这条光线的两个角度?因为如果我可以这样做,我可以在0到360之间为旋转部分取一个随机数,在上下部分之间取一个0到90之间的随机数。 非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

巧合的是,我需要一些非常相似的东西。以下行为将在设置参数中精确地生成某个预制件(objectToSpawnspawnCount次。

辅助类(底部代码)从Yaw,Pitch和Vector生成一个Vector(基本上就是你的距离)。

它的作用:

  • 在设定参数中选择随机方向(偏航和俯仰)
  • 选择随机距离(听起来可以省略此步骤)
  • 计算向量
  • Spawn对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomSpawner : MonoBehaviour {

    public GameObject objectToSpawn;

    public int spawnCount;

    public float minDistance = 2;
    public float maxDistance = 10;

    public float minPitchDegrees = 0;
    public float maxPitchDegrees = 45;

    public float minYawDegrees = -180;
    public float maxYawDegrees = 180;

    void Start () 
    {
        for (int i = 0; i < spawnCount; i++) 
        {
            float distance = minDistance + Random.value * (maxDistance - minDistance);
            float yaw = minYawDegrees + Random.value * (maxYawDegrees - minYawDegrees);
            float pitch = minPitchDegrees + Random.value * (maxPitchDegrees - minPitchDegrees);

            Vector3 position = RotationHelper.ConvertYawPitch (Vector3.forward * distance, yaw, pitch);

            Instantiate (objectToSpawn, position, Quaternion.identity);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class RotationHelper {

    public static Vector3 ConvertYawPitch(Vector3 vector, float yaw, float pitch)
    {
        Quaternion yawRotation = Quaternion.AngleAxis (yaw, Vector3.up);
        Vector3 yawedZAxis = yawRotation * Vector3.left;

        Quaternion pitchRotation = Quaternion.AngleAxis (pitch, yawedZAxis);
        Vector3 yawedVector = yawRotation * vector;

        Vector3 position = pitchRotation * yawedVector;

        return position;
    }
}

在您的具体情况下,参数应为:

  • minDistance = 20
  • maxDistance = 20
  • minPitchDegrees = 0
  • maxPitchDegrees = 0-90,无论你在“切断顶部”之后的角度是什么
  • minYawDegrees = -180
  • maxYawDegrees = 180

答案 1 :(得分:2)

I want objects to spawn randomly at a distance of 20 from a FPS player.

What I understood from this is that you want to spawn objects on the ground, distant 20 units away from the player, in random directions.

You could say the objects need to spawn on the surface of a half sphere with the player as the center.

Now, this is just another way to make things complex. No need to use the sphere to solve this.

If you want to spawn objects on the surface, easiest solution will be to get a random angle in relation with Vector3.up and walk for 20 units to find the desired point.

Script:

public class Spawner : MonoBehaviour 
{
    public Transform player;
    public Transform prefab;

    [Range(10,50)]
    public float distance = 20f;


    IEnumerator Start()
    {
        while (true)
        {
            yield return new WaitForSeconds(0.05f);
            Spawn();
        }
    }

    [ContextMenu("Spawn")]
    public void Spawn()
    {
        Vector3 spawnPoint = FindPoint(player.position, distance, Random.Range(0, 360));
        Instantiate(prefab, spawnPoint, Quaternion.identity, transform);
    }

    [ContextMenu("Clear")]
    public void Clear()
    {
        foreach (var item in transform.GetComponentsInChildren<Transform>())
        {
            if (item != transform)
                DestroyImmediate(item.gameObject);
        }
    }

    Vector3 FindPoint(Vector3 center, float radius, int angle)
    {
        return center + Quaternion.AngleAxis(angle, Vector3.up) * (Vector3.right * radius);
    }
}

Result:

上调用Javascript函数

根据玩家的位置计算随机点:

希望这会有所帮助:)