有没有更好的方法来写这个自上而下的汽车模型
Is there a better way to write this top down car mdoel
我正在写一个自上而下的汽车漂移游戏,我想让汽车在一个圆圈内移动,用户通过转向控制圆的半径,基本上直线转向是一条直线,向左转是一个它将跟随的汽车左侧的小圆圈。随着汽车转向更多(任一侧),我尝试让汽车前部越来越向中心转向,就好像它在漂移一样。
我正在使用 unity,这就是我设计模型的方式。
这是一款手机游戏。所以我给小车写了一个转向控制器,控制它的左右,速度恒定。
有两个刚体
前面的白色盒子和灰色的大盒子都是刚体。用铰链连接。
每一帧的前框在它自己的z轴上旋转一定度数并向前移动一点。因此遵循圆形。转多少由我的转向决定。
我可以让两个身体运动并确保它们遵循圆形并以这种方式移动,但我也希望在碰撞期间有适当的行为,在最终计划中可以有各种碰撞.所以我使用加力方法使它们运动并增加了速度。就其本身而言,前箱是完美的,当我改变转向时它会旋转圆圈变大一切都很好,但是当我添加其他底盘箱时,力都搞砸了。离心力,惯性搅乱一切
基本上我需要汽车漂移是完美的圆,用户应该能够控制圆的半径。最好的建模方法是什么。
这是两个刚体的代码。
前框代码。这只是固定的更新方法。请忽略控件相关代码。没有必要,所以我省略了。
{
//-------------------------
// I N I T.
//-------------------------
current_steering_angle = controls_i.ToSignedRotation(controls_i.getSteeringAngle());
current_steering_angle = (current_steering_angle < 0) ? (current_steering_angle + 90): current_steering_angle;
current_steering_angle -= 45;
//-------------------------
// S P E E D.
//-------------------------
current_speed = Utils.curve_map_linear(0, 45, min_speed, max_speed, Mathf.Abs(current_steering_angle), -1);
_rigid_body.AddRelativeForce(acceleration * Vector3.up);
velocity = transform.InverseTransformVector(_rigid_body.velocity);
if(velocity.y > current_speed){
velocity.y = current_speed;
}
// to prevent reverse movement due to centrifugal force.
velocity.x = 0;
//-------------------------
// R O T A T I O N.
//-------------------------
current_radius = Mathf.Sign(current_steering_angle) * Utils.exp_range_3(0, 45, min_radius, max_radius, Mathf.Abs(current_steering_angle), steering_tension, -1);
current_rot_rate = (velocity.y / (2 * Mathf.PI * current_radius)) * 360;
Vector3 angle = transform.localEulerAngles;
angle.z += (current_rot_rate * Time.fixedDeltaTime);
transform.localEulerAngles = angle;
//-------------------------
// A P P L Y.
//-------------------------
_rigid_body.velocity = transform.TransformVector(velocity);
}
Utils.exp_linear 和 exp_range 函数只是范围映射器有一些张力,以控制控件上转向的灵敏度。
机箱代码。
{
//-------------------------
// I N I T.
//-------------------------
current_steering_angle = controls_i.ToSignedRotation(controls_i.getSteeringAngle());
current_steering_angle = (current_steering_angle < 0) ? (current_steering_angle + 90): current_steering_angle;
current_steering_angle = current_steering_angle - 45;
current_steering_angle = ((float)((int)(current_steering_angle * Mathf.Pow(10, 5))))/Mathf.Pow(10,5);
//-------------------------
// R O T A T I O N.
//-------------------------
current_angle = front_transform.eulerAngles.z - _rigid_body.transform.eulerAngles.z;
current_angle = (Mathf.Abs(current_angle) > 180) ? ((Mathf.Abs(current_angle) - 360) * Mathf.Sign(current_angle)) : current_angle;
current_angle += Mathf.Sign(current_steering_angle) * Utils.curve_map_linear(0, 45, min_angle, max_angle, Mathf.Abs(current_steering_angle), 1);
_rigid_body.transform.RotateAround(front_transform.position, Vector3.forward, current_angle);
//-------------------------
// S P E E D.
//-------------------------
Vector3 velocity = _rigid_body.transform.InverseTransformVector(_rigid_body.velocity);
if (velocity.y < 0){
velocity.y = 0;
}
_rigid_body.velocity = _rigid_body.transform.TransformVector(velocity);
}
我想知道如何在 unity 中实际实现这样的东西。我是这个团结的新手。我到处看了看,有很多 3d 汽车的东西,但自上而下的东西不多。感谢任何类型的反馈。
使其成为非运动的,去掉前轮胎的刚体,使前轮胎成为底盘的child。
处理位置:
制定一个方法,查看汽车的当前位置、玩家转弯的角度,以及returns汽车在适当的圆圈内行驶所需的切向速度:
Vector2 GetTangentialVelocity(...) { }
然后,找出该速度与底盘当前速度之间的差异:
Vector2 velDiff = GetTangentialVelocity(...) - chassis_rigidbody.velocity;
然后,使用 AddForce
和 ForceType.VelocityChange
应用该差异:
chassis_rigidbody.AddForce(velDiff, ForceType.VelocityChange);
处理旋转:
重心前移。您可以通过使刚体变长并将对撞机放在 object 的后部或通过设置 RigidBody.centerOfMass
:
来做到这一点
chassis_rigidbody.centerOfMass = Vector2.up * 0.5;
做一个类似于GetTangentialVelocity
的函数,returns想要的angular速度,找出与chassis_rigidbody.angularVelocity
的区别,然后用AddTorque
和ForceType.VelocityChange
:
Vector2 angVelDiff = GetAngularVelocity(...) - chassis_rigidbody.angularVelocity;
chassis_rigidbody.AddTorque(angVelDiff , ForceType.VelocityChange);
我正在写一个自上而下的汽车漂移游戏,我想让汽车在一个圆圈内移动,用户通过转向控制圆的半径,基本上直线转向是一条直线,向左转是一个它将跟随的汽车左侧的小圆圈。随着汽车转向更多(任一侧),我尝试让汽车前部越来越向中心转向,就好像它在漂移一样。
我正在使用 unity,这就是我设计模型的方式。
这是一款手机游戏。所以我给小车写了一个转向控制器,控制它的左右,速度恒定。
有两个刚体
前面的白色盒子和灰色的大盒子都是刚体。用铰链连接。
每一帧的前框在它自己的z轴上旋转一定度数并向前移动一点。因此遵循圆形。转多少由我的转向决定。
我可以让两个身体运动并确保它们遵循圆形并以这种方式移动,但我也希望在碰撞期间有适当的行为,在最终计划中可以有各种碰撞.所以我使用加力方法使它们运动并增加了速度。就其本身而言,前箱是完美的,当我改变转向时它会旋转圆圈变大一切都很好,但是当我添加其他底盘箱时,力都搞砸了。离心力,惯性搅乱一切
基本上我需要汽车漂移是完美的圆,用户应该能够控制圆的半径。最好的建模方法是什么。
这是两个刚体的代码。
前框代码。这只是固定的更新方法。请忽略控件相关代码。没有必要,所以我省略了。
{ //------------------------- // I N I T. //------------------------- current_steering_angle = controls_i.ToSignedRotation(controls_i.getSteeringAngle()); current_steering_angle = (current_steering_angle < 0) ? (current_steering_angle + 90): current_steering_angle; current_steering_angle -= 45; //------------------------- // S P E E D. //------------------------- current_speed = Utils.curve_map_linear(0, 45, min_speed, max_speed, Mathf.Abs(current_steering_angle), -1); _rigid_body.AddRelativeForce(acceleration * Vector3.up); velocity = transform.InverseTransformVector(_rigid_body.velocity); if(velocity.y > current_speed){ velocity.y = current_speed; } // to prevent reverse movement due to centrifugal force. velocity.x = 0; //------------------------- // R O T A T I O N. //------------------------- current_radius = Mathf.Sign(current_steering_angle) * Utils.exp_range_3(0, 45, min_radius, max_radius, Mathf.Abs(current_steering_angle), steering_tension, -1); current_rot_rate = (velocity.y / (2 * Mathf.PI * current_radius)) * 360; Vector3 angle = transform.localEulerAngles; angle.z += (current_rot_rate * Time.fixedDeltaTime); transform.localEulerAngles = angle; //------------------------- // A P P L Y. //------------------------- _rigid_body.velocity = transform.TransformVector(velocity); }
Utils.exp_linear 和 exp_range 函数只是范围映射器有一些张力,以控制控件上转向的灵敏度。
机箱代码。
{ //------------------------- // I N I T. //------------------------- current_steering_angle = controls_i.ToSignedRotation(controls_i.getSteeringAngle()); current_steering_angle = (current_steering_angle < 0) ? (current_steering_angle + 90): current_steering_angle; current_steering_angle = current_steering_angle - 45; current_steering_angle = ((float)((int)(current_steering_angle * Mathf.Pow(10, 5))))/Mathf.Pow(10,5); //------------------------- // R O T A T I O N. //------------------------- current_angle = front_transform.eulerAngles.z - _rigid_body.transform.eulerAngles.z; current_angle = (Mathf.Abs(current_angle) > 180) ? ((Mathf.Abs(current_angle) - 360) * Mathf.Sign(current_angle)) : current_angle; current_angle += Mathf.Sign(current_steering_angle) * Utils.curve_map_linear(0, 45, min_angle, max_angle, Mathf.Abs(current_steering_angle), 1); _rigid_body.transform.RotateAround(front_transform.position, Vector3.forward, current_angle); //------------------------- // S P E E D. //------------------------- Vector3 velocity = _rigid_body.transform.InverseTransformVector(_rigid_body.velocity); if (velocity.y < 0){ velocity.y = 0; } _rigid_body.velocity = _rigid_body.transform.TransformVector(velocity); }
我想知道如何在 unity 中实际实现这样的东西。我是这个团结的新手。我到处看了看,有很多 3d 汽车的东西,但自上而下的东西不多。感谢任何类型的反馈。
使其成为非运动的,去掉前轮胎的刚体,使前轮胎成为底盘的child。
处理位置:
制定一个方法,查看汽车的当前位置、玩家转弯的角度,以及returns汽车在适当的圆圈内行驶所需的切向速度:
Vector2 GetTangentialVelocity(...) { }
然后,找出该速度与底盘当前速度之间的差异:
Vector2 velDiff = GetTangentialVelocity(...) - chassis_rigidbody.velocity;
然后,使用 AddForce
和 ForceType.VelocityChange
应用该差异:
chassis_rigidbody.AddForce(velDiff, ForceType.VelocityChange);
处理旋转:
重心前移。您可以通过使刚体变长并将对撞机放在 object 的后部或通过设置 RigidBody.centerOfMass
:
chassis_rigidbody.centerOfMass = Vector2.up * 0.5;
做一个类似于GetTangentialVelocity
的函数,returns想要的angular速度,找出与chassis_rigidbody.angularVelocity
的区别,然后用AddTorque
和ForceType.VelocityChange
:
Vector2 angVelDiff = GetAngularVelocity(...) - chassis_rigidbody.angularVelocity;
chassis_rigidbody.AddTorque(angVelDiff , ForceType.VelocityChange);