本文介绍了在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中创建实例化对象后引用它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!