如何在另一个函数中使用函数内部声明的变量? (C#) UnassignedReferenceException: 变量 inRay 没有被赋值
How do you use a variable declared inside a function in another function? (C#) UnassignedReferenceException: The variable inRay has not ben assigned
所以我在 Unity MLAgents 中玩耍,想将 Raycast 击中的对象的位置添加到代理的观察中。
这对我来说真的是一次冒险,因为我对 Unity 或 C# 一无所知,而且我知道这听起来很简单,可能是:
我收到错误 CS0103:名称 'inRay' 在当前上下文中不存在。
好吧,我尝试在全局范围内声明并且错误消失了,但是当 运行 它给我的代码时:
UnassignedReferenceException: 变量 inRay 没有被赋值。
这是一个脚本,我想不出我还能做些什么来解决参考问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
public class AgentBasicController : Agent
{
private Rigidbody rigidA;
private float yThrust = 0.125f;
private float moveSpeed = 5f;
private float timer = 60f;
public Transform inRay;
public override void Initialize()
{
rigidA = GetComponent<Rigidbody>();
}
public override void OnEpisodeBegin()
{
timer = 60f;
if (timer <= 0f)
{
SetReward(-1F);
timer = 60f;
}
}
public override void CollectObservations(VectorSensor sens)
{
sens.AddObservation(transform.localPosition);
sens.AddObservation(inRay.localPosition);
}
public override void OnActionReceived(ActionBuffers acts)
{
int moveX = acts.DiscreteActions[0];
int moveZ = acts.DiscreteActions[1];
if (Mathf.FloorToInt(acts.DiscreteActions[2]) == 1)
{
Jump();
}
if (Mathf.FloorToInt(acts.DiscreteActions[3]) == 1)
{
SensRay();
}
Vector3 addForce = new Vector3(0, 0, 0);
switch (moveX)
{
case 0: addForce.x = 0f; break;
case 1: addForce.x = -1f; break;
case 2: addForce.x = +1f; break;
}
switch (moveZ)
{
case 0: addForce.z = 0f; break;
case 1: addForce.z = -1f; break;
case 2: addForce.z = +1f; break;
}
rigidA.velocity = addForce * moveSpeed + new Vector3(0, rigidA.velocity.y, 0);
}
public override void Heuristic(in ActionBuffers actsOut)
{
ActionSegment<int> discreteActs = actsOut.DiscreteActions;
switch (Mathf.RoundToInt(Input.GetAxisRaw("Horizontal")))
{
case -1: discreteActs[0] = 1; break;
case 0: discreteActs[0] = 0; break;
case +1: discreteActs[0] = 2; break;
}
switch (Mathf.RoundToInt(Input.GetAxisRaw("Vertical")))
{
case -1: discreteActs[1] = 1; break;
case 0: discreteActs[1] = 0; break;
case +1: discreteActs[1] = 2; break;
}
discreteActs[2] = 0;
if (Input.GetKey(KeyCode.Space))
{
discreteActs[2] = 1;
}
discreteActs[3] = 0;
if(Input.GetKey(KeyCode.R))
{
discreteActs[3] = 1;
}
}
private void Jump()
{
if (transform.localPosition.y <= 1f)
{
rigidA.AddForce(new Vector3(0, yThrust , 0), ForceMode.Impulse);
}
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Goal"))
{
SetReward(+1f);
EndEpisode();
}
if (other.CompareTag("Rift"))
{
SetReward(-1f);
EndEpisode();
}
}
public void SensRay()
{
RaycastHit rayHit;
if (Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.forward)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.right)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.left)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.back)), out rayHit))
{
var inRay = rayHit.transform;
if (inRay.CompareTag("Goal"))
{
Vector3 target = rayHit.transform.localPosition;
Vector3 current = transform.localPosition;
transform.localPosition = Vector3.MoveTowards(current, target, moveSpeed);
}
}
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.forward)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.right)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.left)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.back)), Color.yellow);
}
private void Update()
{
if (timer <= 0f)
{
SetReward(-1F);
timer = 60f;
}
}
}
var inRay = rayHit.transform;
您正在创建一个新的局部变量,而不是在此处分配您的成员变量。删除 var
.
您仍然应该在使用之前检查您的成员变量是否已分配,也许 if (inRayr != null)
可以提供帮助。
您在代理中声明的字段应在构造函数中实例化。所以只要给它一个默认值或者让它为空。
编译器优化此值并抛出异常,因为它认为该字段从未声明过,因此也从未使用过。
如您所见,所有其他字段都已设置为默认值,并且不会引发错误。
所以我在 Unity MLAgents 中玩耍,想将 Raycast 击中的对象的位置添加到代理的观察中。 这对我来说真的是一次冒险,因为我对 Unity 或 C# 一无所知,而且我知道这听起来很简单,可能是:
我收到错误 CS0103:名称 'inRay' 在当前上下文中不存在。
好吧,我尝试在全局范围内声明并且错误消失了,但是当 运行 它给我的代码时:
UnassignedReferenceException: 变量 inRay 没有被赋值。
这是一个脚本,我想不出我还能做些什么来解决参考问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
public class AgentBasicController : Agent
{
private Rigidbody rigidA;
private float yThrust = 0.125f;
private float moveSpeed = 5f;
private float timer = 60f;
public Transform inRay;
public override void Initialize()
{
rigidA = GetComponent<Rigidbody>();
}
public override void OnEpisodeBegin()
{
timer = 60f;
if (timer <= 0f)
{
SetReward(-1F);
timer = 60f;
}
}
public override void CollectObservations(VectorSensor sens)
{
sens.AddObservation(transform.localPosition);
sens.AddObservation(inRay.localPosition);
}
public override void OnActionReceived(ActionBuffers acts)
{
int moveX = acts.DiscreteActions[0];
int moveZ = acts.DiscreteActions[1];
if (Mathf.FloorToInt(acts.DiscreteActions[2]) == 1)
{
Jump();
}
if (Mathf.FloorToInt(acts.DiscreteActions[3]) == 1)
{
SensRay();
}
Vector3 addForce = new Vector3(0, 0, 0);
switch (moveX)
{
case 0: addForce.x = 0f; break;
case 1: addForce.x = -1f; break;
case 2: addForce.x = +1f; break;
}
switch (moveZ)
{
case 0: addForce.z = 0f; break;
case 1: addForce.z = -1f; break;
case 2: addForce.z = +1f; break;
}
rigidA.velocity = addForce * moveSpeed + new Vector3(0, rigidA.velocity.y, 0);
}
public override void Heuristic(in ActionBuffers actsOut)
{
ActionSegment<int> discreteActs = actsOut.DiscreteActions;
switch (Mathf.RoundToInt(Input.GetAxisRaw("Horizontal")))
{
case -1: discreteActs[0] = 1; break;
case 0: discreteActs[0] = 0; break;
case +1: discreteActs[0] = 2; break;
}
switch (Mathf.RoundToInt(Input.GetAxisRaw("Vertical")))
{
case -1: discreteActs[1] = 1; break;
case 0: discreteActs[1] = 0; break;
case +1: discreteActs[1] = 2; break;
}
discreteActs[2] = 0;
if (Input.GetKey(KeyCode.Space))
{
discreteActs[2] = 1;
}
discreteActs[3] = 0;
if(Input.GetKey(KeyCode.R))
{
discreteActs[3] = 1;
}
}
private void Jump()
{
if (transform.localPosition.y <= 1f)
{
rigidA.AddForce(new Vector3(0, yThrust , 0), ForceMode.Impulse);
}
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Goal"))
{
SetReward(+1f);
EndEpisode();
}
if (other.CompareTag("Rift"))
{
SetReward(-1f);
EndEpisode();
}
}
public void SensRay()
{
RaycastHit rayHit;
if (Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.forward)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.right)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.left)), out rayHit) ||
Physics.Raycast(transform.localPosition, (transform.TransformDirection(Vector3.back)), out rayHit))
{
var inRay = rayHit.transform;
if (inRay.CompareTag("Goal"))
{
Vector3 target = rayHit.transform.localPosition;
Vector3 current = transform.localPosition;
transform.localPosition = Vector3.MoveTowards(current, target, moveSpeed);
}
}
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.forward)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.right)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.left)), Color.yellow);
Debug.DrawRay(transform.position, (transform.TransformDirection(Vector3.back)), Color.yellow);
}
private void Update()
{
if (timer <= 0f)
{
SetReward(-1F);
timer = 60f;
}
}
}
var inRay = rayHit.transform;
您正在创建一个新的局部变量,而不是在此处分配您的成员变量。删除 var
.
您仍然应该在使用之前检查您的成员变量是否已分配,也许 if (inRayr != null)
可以提供帮助。
您在代理中声明的字段应在构造函数中实例化。所以只要给它一个默认值或者让它为空。 编译器优化此值并抛出异常,因为它认为该字段从未声明过,因此也从未使用过。 如您所见,所有其他字段都已设置为默认值,并且不会引发错误。