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中创建实例化对象后引用它们
基础教程推荐
- Moq It.Is<>不匹配 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- WPF 模态进度窗口 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
