Referencing Instantiated objects after their creation in Unity(在Unity中创建实例化对象后引用它们)
问题描述
嗨!
在评论中与Ruzihm讨论之后。我现在已经创建了我的游戏的一个简单版本,以便更好地提出我的问题。
现在的问题是,因为我无法手动创建到检查器中testObject字段的连接。现在如何告诉Unity在游戏运行时使用我的实例化对象?
对于一次可能有100个活动单位的RTS游戏来说,这是一个很好的解决方案吗?这里的最终目标是将此力应用于光标周围的半径。我正在考虑使用Physics.OverlapSphere
以下是我所拥有的最小方案:
- 新建Unity场景
 - 已将InputManager连接到主摄像机。
 - 创建了一个胶囊和一个平面。
 - 已将ApplyForce添加到胶囊中
 - 从胶囊创建预制件并将其从场景中删除。
 - 在InputManager中,我添加了按空格键实例化带有ApplyForce脚本的胶囊的功能。
 - 将胶囊预制拖到InputManager";objectToGenerate;
 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
    public class InputManager : MonoBehaviour
    {
        public GameObject testObject;
        public ApplyForce onSpawnTest;
        public GameObject objectToGenerate;
        void Start()
        {
            onSpawnTest = testObject.GetComponent<ApplyForce>();
        }
        void Update()
        {
            if(Input.GetKeyDown(KeyCode.Space))
            {
            Instantiate(objectToGenerate);
            }
            
            if (Input.GetMouseButton(0))
            {
                onSpawnTest.PushForward();
            }
        }
    }
}
我附加到胶囊的ApplyForce脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
    public class ApplyForce : MonoBehaviour
    {
        public float moveSpeed;
        Rigidbody rb;
        void Start()
        {
            rb = GetComponent<Rigidbody>();
            Debug.Log("A Mite has spawned!");
        }
        public void PushForward()
        {
            rb.AddRelativeForce(Vector3.up * moveSpeed * Time.deltaTime);
            Debug.Log("A force of: " + moveSpeed + " is being added.");
        }
    }
}
推荐答案
好的,您正在创建对象的新实例,但是您的输入管理器立即忘记了它们(请注意,您没有对返回值做任何操作)。InputManager只知道在其Start中创建的ApplyForce(然后根据鼠标输入与其交互),而您的ApplyForce脚本对任何InputManager一无所知。因此,只有第一个实例对鼠标输入做出反应就不足为奇了。
InputManager和/或您的ApplyForce执行某些操作。您的InputManager可以记住它创建的实例(这是不够的,因为例如,如果地图触发器创建了新的玩家可控单位怎么办),或者它可以每次都去查找单位。您的ApplyForce可以在创建InputManager时注册到InputManager,但之后您需要遍历这些单元并找出鼠标下面有哪些单元。
InputManager在需要时查找单位即可。如下所示,在评论中说明:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GL.RTS.Mites
{
    public class InputManager : MonoBehaviour
    {
        public GameObject testObject;
        public ApplyForce onSpawnTest;
        public GameObject objectToGenerate;
        
        private Camera mainCam;
        // which layers to consider for cursor detection
        [SerializeField] LayerMask cursorLayerMask;
        // how big for cursor detection
        [SerializeField] float cursorRadius;
        void Awake()
        {
            // cache main camera
            mainCam = Camera.main;
        }
        void Update()
        {
            if(Input.GetKeyDown(KeyCode.Space))
            {
                Instantiate(objectToGenerate);
            }
            
            if (Input.GetMouseButton(0))
            {
                Collider[] colls = FindCollidersUnderCursor();
                // check each collider for an applyforce and use it if present
                foreach( Collider coll in colls)
                {
                    ApplyForce af = coll.GetComponent<ApplyForce>();
                    if (af != null) 
                    {
                        af.PushForward();
                    }
                } 
            }
        }
        Collider[] FindCollidersUnderCursor()
        {
            // find ray represented by cursor position on screen
            // and find where it intersects with ground
            // This technique is great for if your camera can change
            // angle or distance from the playing field.
            // It uses mathematical rays and plane, no physics
            // calculations needed for this step. Very performant.
            Ray cursorRay = mainCam.ScreenPointToRay(Input.mousePosition);
            Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
            if (groundPlane.Raycast(cursorRay, out float cursorDist))
            {
                Vector3 worldPos = cursorRay.GetPoint(cursorDist);
                // Check for triggers inside sphere that match layer mask
                return Physics.OverlapSphere(worldPos, cursorRadius, 
                        cursorLayerMask.value, QueryTriggerInteraction.Collide);
            }
            // if doesn't intersect with ground, return nothing
            return new Collider[0];
        }
    }
}
当然,这将要求您感兴趣的每个单元都有触发对撞器。
这篇关于在Unity中创建实例化对象后引用它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在Unity中创建实例化对象后引用它们
				
        
 
            
        - 输入按键事件处理程序 2022-01-01
 - C# 中多线程网络服务器的模式 2022-01-01
 - 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
 - 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
 - WebMatrix WebSecurity PasswordSalt 2022-01-01
 - 如何用自己压缩一个 IEnumerable 2022-01-01
 - MoreLinq maxBy vs LINQ max + where 2022-01-01
 - C#MongoDB使用Builders查找派生对象 2022-09-04
 - 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
 - Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
 
						
						
						
						
						
				
				
				
				