C# Unity 2017.3:transform.position分配尝试无效。输入位置为{-无穷大,0,0}
我一直在尝试为2D游戏构建一个光线投射控制器,并遵循了一些教程系列来帮助我更好地理解这是如何完成的。到目前为止,一切都进行得很顺利,实际上我已经完成了关于这个主题的几篇教程 然而,在使用当前的角色控制器时,即使没有编译器错误,我也会在游戏中遇到大量错误。我从未见过这个错误,也无法在网上找到解决方法。基本上,我的角色在游戏中消失了(我假设它被无限地向左移动) 我得到两个错误:“transform.position赋值尝试无效。输入位置为{-无穷大,0,0}”,和“无效世界AABB。对象太大或离原点太远。” 错误发生在第90行:C# Unity 2017.3:transform.position分配尝试无效。输入位置为{-无穷大,0,0},c#,unity3d,game-engine,C#,Unity3d,Game Engine,我一直在尝试为2D游戏构建一个光线投射控制器,并遵循了一些教程系列来帮助我更好地理解这是如何完成的。到目前为止,一切都进行得很顺利,实际上我已经完成了关于这个主题的几篇教程 然而,在使用当前的角色控制器时,即使没有编译器错误,我也会在游戏中遇到大量错误。我从未见过这个错误,也无法在网上找到解决方法。基本上,我的角色在游戏中消失了(我假设它被无限地向左移动) 我得到两个错误:“transform.position赋值尝试无效。输入位置为{-无穷大,0,0}”,和“无效世界AABB。对象太大或离原点
public void LateUpdate()
{
Move(Velocity * Time.deltaTime);
}
和126:
characterTransform.Translate(deltaMovement, Space.World);
我尝试了很多不同的方法,包括更改角色的比例、将vector2更改为vector3、删除Space.World以及直接调用transform.Translate(而不是使用我的characterTransform)。似乎什么都不起作用,出于某种原因,我的相机有时也会给我一个错误,尽管很难再现。如果我删除任何一行代码,我都不会出错,但很明显,我的角色无法移动
错误的屏幕截图:
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
///
///使用光线投射处理角色移动
///
公共类CharacterController2D:单行为{
//定义光线数
私有常量int totalHorizontalRays=8;
私有常量int TotalVeritCalray=4;
private raycastOriginates raycastOriginates;//引用raycastOriginates结构
private const float skinWidth=.02f;//定义光线的蒙皮宽度,该宽度将光线的原点稍微放置在角色的长方体碰撞器内
私有静态只读浮点slopeLimitTanget=Mathf.Tan(75f*Mathf.Deg2Rad);
public LayerMask platformMask;//定义将用于确定不同层如何与角色交互的LayerMask
公共ControllerParameters2D defaultParameters;//引用ControllerParameters2D类
public ControllerState2D State{get;private set;}//引用ControllerState2D类
public ControllerParameters2D参数{get{return overrideParameters??defaultParameters;}}//返回更新的参数,或者如果overrideParameters为空,则返回默认参数
公共向量2速度{get{return Velocity;}}}//定义角色的速度
public bool CanJump{get{return false;}}}//定义字符是否可以跳转
public bool HandleCollisions{get;set;}//定义角色是否需要处理冲突(因为它与某个对象冲突)
私有向量2 velocity;//velocity属性的字段
private BoxCollider2D boxCollider;//引用角色上的框碰撞器
private ControllerParameters2D overrideParameters;//引用更新的参数(即更新的参数,而不是默认参数)
私有转换characterTransform;//引用角色的转换
私有向量3 localScale;//引用角色的比例
//光线投射之间的距离
私人浮动日间水平距离;
道路之间的私人浮动垂直距离;
private struct RaycastOrigins//存储定义在框碰撞器上创建光线投射的位置的值类型
{
公共向量2 topLeft,topRight;//创建变量以定义光线投射的上部位置
public Vector2 bottomLeft,bottomRight;//创建变量以定义光线投射的较低位置
}
公共图书馆
{
State=new ControllerState2D();//访问ControllerState2D脚本
boxCollider=GetComponent();//访问角色的框碰撞器
characterTransform=transform;//访问角色的变换
localScale=transform.localScale;//访问角色的比例
//获取光线间距
两天之间的水平距离=计算水平光线间距();
道路之间的垂直距离=计算平均道路间距();
}
公开作废开始()
{
}
公共无效添加力(矢量2力)
{
速度+=力;
}
公共无效设置力(矢量2力)
{
速度=力;
}
公共无效设置水平力(浮动x)
{
速度x=x;
}
公共无效设置垂直力(浮动y)
{
速度y=y;
}
公共跳转
{
}
公共更新()
{
Move(Velocity*Time.deltaTime);//按角色的速度移动角色,按时间缩放
}
公共无效OnTriggerInter2d(碰撞的R2D其他)
{
}
公共无效OnTiggerExit2D(碰撞R2D其他)
{
}
私有无效移动(矢量2增量移动)
{
var wasgorded=State.IsCollidingBelow;//跟踪字符是否固定
State.Reset();//重置状态
if(HandleCollisions)//如果角色应该处理冲突
{
手持平台();
CalculateRaycastOrigins();
if(deltaMovement.y<0&&wasgorded)//如果角色正在向下移动,并且之前已被固定。。。
{
下坡(参考三角洲运动);
}
if(Mathf.Abs(deltaMovement.x)>.001f)//如果角色正在向左或向右移动。。。
{
水平移动(参考三角移动);
}
movevertical(ref deltaMovement);//始终调用movevertical方法,因为角色上始终施加重力
}
characterTransform.Translate(deltaMovement,Space.World);//在考虑了所有可能的移动场景后移动角色
如果(Time.deltaTime>0)
{
velocity=deltaMovement/Time.deltaTime;//将当前速度设置为等于移动中的变化
}
//将速度钳制为参数中定义的最大x和y速度
速度x=M
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Handles the character movement with raycasts
/// </summary>
public class CharacterController2D : MonoBehaviour {
//Defines the number of rays
private const int totalHorizontalRays = 8;
private const int totalVeritcalRays = 4;
private RaycastOrigins raycastOrigins; //References the RayCastOrigins struct
private const float skinWidth = .02f; //Defines the skin width of the rays, which places the origin point of the rays slightly inside the character's box collider
private static readonly float slopeLimitTanget = Mathf.Tan(75f * Mathf.Deg2Rad);
public LayerMask platformMask; //Defines the layermask that will be used to determine how different layers interact with the character
public ControllerParameters2D defaultParameters; //References the ControllerParameters2D class
public ControllerState2D State { get; private set; } //References the ControllerState2D class
public ControllerParameters2D Parameters { get { return overrideParameters ?? defaultParameters; } } //Returns updated parameters, or default parameters if overrideParameters is null
public Vector2 Velocity { get { return velocity; } } //Defines the character's velocity
public bool CanJump { get { return false; } } //Defines whether or not the character can jump
public bool HandleCollisions { get; set; } //Defines whether or not the character needs to handle collisions (because it is colliding with something)
private Vector2 velocity; //The field for the Velocity property
private BoxCollider2D boxCollider; //References the box collider on the character
private ControllerParameters2D overrideParameters; //References the updated parameters (that is, the updated parameters, not the default ones)
private Transform characterTransform; //References the character's transform
private Vector3 localScale; //References the character's scale
//The distance between raycasts
private float horizontalDistanceBetweenRays;
private float verticalDistanceBetweenRays;
private struct RaycastOrigins //Stores the value types that define where the raycasts are created on the box collider
{
public Vector2 topLeft, topRight; //Creates variables to define the upper position of the raycasts
public Vector2 bottomLeft, bottomRight; //Creates variables to define the lower position of the raycasts
}
public void Awake()
{
State = new ControllerState2D(); //Accesses the ControllerState2D script
boxCollider = GetComponent<BoxCollider2D>(); //Accesses the character's box collider
characterTransform = transform; //Accesses the character's transform
localScale = transform.localScale; //Accesses the character's scale
//Gets the ray spacing
horizontalDistanceBetweenRays = CalculateHorizontalRaySpacing();
verticalDistanceBetweenRays = CalculateVerticalRaySpacing();
}
public void Start()
{
}
public void AddForce(Vector2 force)
{
velocity += force;
}
public void SetForce(Vector2 force)
{
velocity = force;
}
public void SetHorizontalForce(float x)
{
velocity.x = x;
}
public void SetVerticalForce(float y)
{
velocity.y = y;
}
public void Jump()
{
}
public void LateUpdate()
{
Move(Velocity * Time.deltaTime); //Moves the character per its velocity, scaled by time
}
public void OnTriggerEnter2D(Collider2D other)
{
}
public void OnTriggerExit2D(Collider2D other)
{
}
private void Move(Vector2 deltaMovement)
{
var wasGrounded = State.IsCollidingBelow; //Keeps track of whether or not the character is grounded
State.Reset(); //Resets the state
if (HandleCollisions) //If the character should handle collisions
{
HandlePlatforms();
CalculateRaycastOrigins();
if (deltaMovement.y < 0 && wasGrounded) //If the character is moving down, and was previously grounded...
{
ClimbDownSlope(ref deltaMovement);
}
if (Mathf.Abs(deltaMovement.x) > .001f) //If the character is moving left or right...
{
MoveHorizontally(ref deltaMovement);
}
MoveVertically(ref deltaMovement); //Calls the MoveVertically method always, since the character always has the force of gravity enacted on it
}
characterTransform.Translate(deltaMovement, Space.World); //Moves the character after all potential movement scenarios have been accounted for
if (Time.deltaTime > 0)
{
velocity = deltaMovement / Time.deltaTime; //Sets the current velocity equal to the change in movement
}
//Clamps the velocity to the maximum x and y velocity defined in Parameters
velocity.x = Mathf.Min(velocity.x, Parameters.maxVelocity.x);
velocity.y = Mathf.Min(velocity.y, Parameters.maxVelocity.y);
if (State.IsMovingUpSlope) //If the character is moving up a slope...
{
velocity.y = 0;
}
}
private void MoveHorizontally(ref Vector2 deltaMovement)
{
var isGoingRight = deltaMovement.x > 0; //Defines if the character is going right
var rayDistance = Mathf.Abs(deltaMovement.x) + skinWidth; //Defines the distance of the raycasts
var rayDirection = isGoingRight ? Vector2.right : -Vector2.right; //Defines in which direction the rays will shoot, depdending on character direction
var rayOrigin = isGoingRight ? raycastOrigins.bottomRight : raycastOrigins.bottomLeft; //Defines the current ray origin
for (var i = 0; i < totalHorizontalRays; i++) //Loops through each of the 8 horizontal rays
{
var rayVector = new Vector2(rayOrigin.x, rayOrigin.y + (i * verticalDistanceBetweenRays)); //Builds the rays (stacking them up with each ray that is added)
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
var rayCastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, platformMask); //Actually draws the rays
if (!rayCastHit) //If the raycast hits something... (rayCastHit is true)
{
continue;
}
if (i == 0 && ClimbUpSlope(ref deltaMovement, Vector2.Angle(rayCastHit.normal, Vector2.up), isGoingRight)) //If the character is now climbing a slope...
{
break;
}
deltaMovement.x = rayCastHit.point.x - rayVector.x; //Clamps horizontal movement based on ray collision
rayDistance = Mathf.Abs(deltaMovement.x); //Clamps the ray distance based on how far the character is allowed to move (i.e. ensures the rays end at walls)
if (isGoingRight) //If the character is going right...
{
deltaMovement.x -= skinWidth; //Ensures that the character moves with the correct value (otherwise would be able to move slightly more based on skinWidth value)
State.IsCollidingRight = true;
}
else //If the character is going left...
{
deltaMovement.x += skinWidth;
State.IsCollidingLeft = true;
}
if (rayDistance < skinWidth + .0001f) //If a collision gets bugged for some reason...
{
break;
}
}
}
private void MoveVertically(ref Vector2 deltaMovement)
{
}
private void ClimbDownSlope(ref Vector2 deltaMovement)
{
}
private bool ClimbUpSlope(ref Vector2 deltaMovement, float angle, bool isGoingRight)
{
return false;
}
private void HandlePlatforms()
{
}
private float CalculateHorizontalRaySpacing()
{
Bounds bounds = boxCollider.bounds; //Sets the 'bounds' variable equal to the bounds of the box collider on the game object
bounds.Expand(skinWidth * -2); //Enforces the skinWidth variable
return bounds.size.y / (totalHorizontalRays - 1); //Ensures that all rays are spaced evenly on the sides of the box collider
}
private float CalculateVerticalRaySpacing()
{
Bounds bounds = boxCollider.bounds; //Sets the 'bounds' variable equal to the bounds of the box collider on the game object
bounds.Expand(skinWidth * -2); //Enforces the skinWidth variable
return bounds.size.x / (totalVeritcalRays - 1); //Ensures that all rays are spaced evenly on the bottom and top of the box collider
}
private void CalculateRaycastOrigins()
{
Bounds bounds = boxCollider.bounds; //Sets the 'bounds' variable equal to the bounds of the box collider on the game object
bounds.Expand(skinWidth * -2); //Enforces the skinWidth variable
//Creates the starting positions of the raycasts
raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y);
raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y);
raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y);
raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y);
}