用布娃娃随机生成(非刚体)对象剪辑

问题描述 投票:0回答:1

我一直在使用 ML-Agents 库并尝试在随机生成的目标对象周围创建边框。我创建了它,修改了脚本以将其传送到与目标相同的位置,但它经常会产生剪辑到布娃娃中,同时不会将其检测为碰撞(这会将其重置为随机位置并解决问题),而是粘合我的布娃娃掉到了地上。

我对 Unity 相当陌生,所以请随意发布所谓的明显修复。

我尝试过的事情:

  1. 设置刚体 - 边框拧得太紧,仍然存在剪裁
  2. 弄乱碰撞设置 - 对剪切完全没有影响
  3. 测量目标和布娃娃之间的距离,并重新生成随机位置 - 没有做任何事情
  4. 添加一个计时器,之后位置应重新生成 - 边界部分(由 4 根光束组成)开始疯狂地传送到各处)

我的 TargetSpawner 脚本:

using UnityEngine;
using Random = UnityEngine.Random;
using Unity.MLAgents;
using UnityEngine.Events;

namespace Unity.MLAgentsExamples
{
    /// <summary>
    /// Utility class to allow target placement and collision detection with an agent
    /// Add this script to the target you want the agent to touch.
    /// Callbacks will be triggered any time the target is touched with a collider tagged as 'tagToDetect'
    /// </summary>
    public class TargetController : MonoBehaviour
    {

        [Header("Collider Tag To Detect")]
        public string tagToDetect = "agent"; //collider tag to detect

        [Header("Target Placement")]
        public float spawnRadius; //The radius in which a target can be randomly spawned.
        public bool respawnIfTouched; //Should the target respawn to a different position when touched

        [Header("Target Fell Protection")]
        public bool respawnIfFallsOffPlatform = true; //If the target falls off the platform, reset the position.
        public float fallDistance = 5; //distance below the starting height that will trigger a respawn

        private Vector3 m_startingPos; //the starting position of the target

        [System.Serializable]
        public class TriggerEvent : UnityEvent<Collider>
        {
        }

        [Header("Trigger Callbacks")]
        public TriggerEvent onTriggerEnterEvent = new TriggerEvent();
        public TriggerEvent onTriggerStayEvent = new TriggerEvent();
        public TriggerEvent onTriggerExitEvent = new TriggerEvent();

        [System.Serializable]
        public class CollisionEvent : UnityEvent<Collision>
        {
        }

        [Header("Collision Callbacks")]
        public CollisionEvent onCollisionEnterEvent = new CollisionEvent();
        public CollisionEvent onCollisionStayEvent = new CollisionEvent();
        public CollisionEvent onCollisionExitEvent = new CollisionEvent();
    public GameObject boundary;
    public GameObject ragdoll;
        // Start is called before the first frame update
        void OnEnable()
        {

            m_startingPos = transform.position;
            if (respawnIfTouched)
            {
                MoveTargetToRandomPosition();
            }
        }
        void Update()
        {

            if (respawnIfFallsOffPlatform)
            {
                if (transform.position.y < m_startingPos.y - fallDistance)
                {
                    Debug.Log($"{transform.name} Fell Off Platform");
                    MoveTargetToRandomPosition();
                }
            }
        }

        /// <summary>
        /// Moves target to a random position within specified radius.
        /// </summary>
        public void MoveTargetToRandomPosition()
        {
            var newTargetPos = m_startingPos + (Random.insideUnitSphere * spawnRadius);
        float dis = Vector3.Distance(newTargetPos, ragdoll.transform.position);
        while (dis < 10){
            newTargetPos = m_startingPos + (Random.insideUnitSphere * spawnRadius);
            dis = Vector3.Distance(newTargetPos, ragdoll.transform.position);
        }
            newTargetPos.y = m_startingPos.y;
            transform.position = newTargetPos;
        boundary.transform.position = newTargetPos + new Vector3(0f, -0.75f,-2f);
        }

        private void OnCollisionEnter(Collision col)
        {
            if (col.transform.CompareTag(tagToDetect))
            {
                onCollisionEnterEvent.Invoke(col);
                if (respawnIfTouched)
                {
                    MoveTargetToRandomPosition();
                }
            }
        }

        private void OnCollisionStay(Collision col)
        {
            if (col.transform.CompareTag(tagToDetect))
            {
                onCollisionStayEvent.Invoke(col);
            }
        }

        private void OnCollisionExit(Collision col)
        {
            if (col.transform.CompareTag(tagToDetect))
            {
                onCollisionExitEvent.Invoke(col);
            }
        }

        private void OnTriggerEnter(Collider col)
        {
            if (col.CompareTag(tagToDetect))
            {
                onTriggerEnterEvent.Invoke(col);
            }
        }

        private void OnTriggerStay(Collider col)
        {
            if (col.CompareTag(tagToDetect))
            {
                onTriggerStayEvent.Invoke(col);
            }
        }

        private void OnTriggerExit(Collider col)
        {
            if (col.CompareTag(tagToDetect))
            {
                onTriggerExitEvent.Invoke(col);
            }
        }
    }
}

任何帮助将不胜感激。
预先感谢
干杯!

c# unity-game-engine clipping ml-agent
1个回答
0
投票

如果我理解正确的话,你的整个问题是你的边界没有在正确的位置产生。 '剪辑它'就像在产卵到一半时那样? 如果是这样,那么你的全部问题就出在你的传送机制上

boundary.transform.position = newTargetPos + new Vector3(0f, -0.75f,-2f);

对我来说这似乎是个问题,尝试尝试传送你的边界,无论目标物体如何。这样做应该可以告诉你为什么它没有传送到它应该传送到的确切位置。也许您在某个地方的比例不均匀,理论上可能会产生问题。

此外,根据您想要制作的游戏的程度,您可以制作一个不太干净但有效的解决方案。您可以将目标作为边界的父级,并使边界在围绕目标的同时随目标移动,一旦您对它们的位置感到满意,就取消它们的父级。可能会起作用(;

© www.soinside.com 2019 - 2024. All rights reserved.