webnetweaver Posted Thursday at 05:34 PM Share Posted Thursday at 05:34 PM (edited) Im going through Third Person Cross Country Arcade Racing tutorial project and everything was going fine until the last step where I added the Gameplay and I started getting this error. I tried searching for this error, and saw a solution but when I tried the solution it didnt work. This is the second time I am running into an error having to do with double precision vs float. The first issue had to do with an example project included with the engine. The solution was to set the correct build configuration. This time it's different because this is a vanilla project I started myself and there's no default build configurations to choose from. The error is occurring on this line: player.Reset(reset_transform); How do I fix this error once and for all? Edited Friday at 06:22 AM by webnetweaver Link to comment
fox Posted Friday at 04:53 AM Share Posted Friday at 04:53 AM Hi, @webnetweaver! Yep, one might encounter some conversion issues in case of inconsistent use of precision across a project. That's why it is recommended to use things like Mat4, Vec3, and so on in your code where appropriate, and check the UNIGINE_DOUBLE define to set proper types, like in this section: #region Math Variables #if UNIGINE_DOUBLE using Vec3 = Unigine.dvec3; using Mat4 = Unigine.dmat4; #else using Vec3 = Unigine.vec3; using Mat4 = Unigine.mat4; #endif #endregion A couple of questions: Which precision setting does your project have Double or Float? Could you provide the code of your GameManager.cs component? Thanks! Link to comment
webnetweaver Posted Friday at 05:34 AM Author Share Posted Friday at 05:34 AM (edited) 42 minutes ago, fox said: Hi, @webnetweaver! Yep, one might encounter some conversion issues in case of inconsistent use of precision across a project. That's why it is recommended to use things like Mat4, Vec3, and so on in your code where appropriate, and check the UNIGINE_DOUBLE define to set proper types, like in this section: #region Math Variables #if UNIGINE_DOUBLE using Vec3 = Unigine.dvec3; using Mat4 = Unigine.dmat4; #else using Vec3 = Unigine.vec3; using Mat4 = Unigine.mat4; #endif #endregion A couple of questions: Which precision setting does your project have Double or Float? Could you provide the code of your GameManager.cs component? Thanks! The project is set to Double Precision from the label in the launcher. Here is the GameManager.cs, the code is from here: https://developer.unigine.com/en/docs/latest/learn/12_arcade/6?rlang=cpp using System; using System.Collections; using System.Collections.Generic; using Unigine; #region Math Variables #if UNIGINE_DOUBLE using Vec3 = Unigine.dvec3; using Mat4 = Unigine.dmat4; #else using Vec3 = Unigine.vec3; using Mat4 = Unigine.mat4; #endif #endregion [Component(PropertyGuid = "b14da50f9242b8427021aa4d17aaf46e4616c42a")] public class GameManager : Component { // links to the game logic components [ShowInEditor] private CarPlayer player = null; [ShowInEditor] private Timer timer = null; [ShowInEditor] private Track track = null; [ShowInEditor] private UI ui = null; [ShowInEditor] private HUD hud = null; // speed in km/h to calculate the standard track finish time [ShowInEditor] private float default_speed = 1.0f; // variable to store the best result private double best_time = 0.0; // position to reset the car location and track starting point private Mat4 reset_transform = Mat4.IDENTITY; private Mat4 start_track_transform = Mat4.IDENTITY; // end game screen when time is over private void OnTimeLeft() { timer.Stop(); ui.Show(UI.Status.Lose); InputController.IsEnabled = false; } // end game screen on finishing the track private void OnTrackEnd() { timer.Stop(); best_time = timer.TimePassed; ui.Show(UI.Status.Win); InputController.IsEnabled = false; } // update the car reset position in every checkpoint private void OnCheckPoint() { reset_transform = player.node.WorldTransform; } [Method(Order = 2)] private void Init() { reset_transform = player.node.WorldTransform; Map.CreateCarMarker(player); ui.SetNewClickEventHandler(StartTrack); ui.SetRestartClickEventHandler(RestartTrack); timer.SetTimeLeftEventHandler(OnTimeLeft); best_time = 0.0; track.SetTrackEndEventHandler(OnTrackEnd); track.SetCheckPointEventHandler(OnCheckPoint); StartTrack(); } private void Update() { if (InputController.GetAction(InputController.InputActionType.Reset) > 0.0f) player.Reset(reset_transform); // update the speed and time display hud.SetSpeed(player.Speed); hud.SetTime(timer.TimePassed); } private void Start() { reset_transform = start_track_transform; timer.Start(best_time); hud.SetBestTime(best_time); ui.Hide(); InputController.IsEnabled = true; } // when starting the track, calculate the standard track finish time private void StartTrack() { start_track_transform = player.node.WorldTransform; track.Shuffle(); double length = track.GetLength(player.node.WorldPosition); double default_time = length / default_speed * 3.6f; best_time = default_time; Start(); } private void RestartTrack() { player.Reset(start_track_transform); track.Restart(); Start(); } } The error is occurring on both lines that say: player.Reset(reset_transform). Here is the Car class with the Reset() method:: using System; using System.Collections; using System.Collections.Generic; using Unigine; [Component(PropertyGuid = "b2228d2ad80c5790407b03d47df0295fb3ed433b")] public class Car : Component { // define two modes of movement: forward and reverse protected enum MoveDirection { Forward, Reverse, } // vehicle parameters: acceleration, maximum speed, and wheel turning angle, torque public float acceleration = 50.0f; public float max_velocity = 90.0f; private float max_turn_angle = 30.0f; public float default_torque = 5.0f; // car body length and width public float car_base = 3.0f; public float car_width = 2.0f; // speed of accelerating, braking, and turning public float throttle_speed = 2.0f; public float brake_speed = 1.2f; public float wheel_speed = 2.0f; // service and hand brake force public float brake_damping = 8.0f; public float hand_brake_damping = 30.0f; // references to wheel nodes public Node wheel_fl = null; public Node wheel_fr = null; public Node wheel_rl = null; public Node wheel_rr = null; // references to light nodes: brake and reverse light public Node brake_light = null; public Node reverse_light = null; // wheel joints private JointWheel joint_wheel_fl = null; private JointWheel joint_wheel_fr = null; private JointWheel joint_wheel_rl = null; private JointWheel joint_wheel_rr = null; // define the desired and current values for throttle, brake, steering wheel and hand brake private float target_throttle = 0.0f; private float target_brake = 0.0f; private float target_wheel = 0.0f; private float target_hand_brake = 0.0f; private float current_throttle = 0.0f; private float current_brake = 0.0f; private float current_wheel = 0.0f; private float current_hand_brake = 0.0f; // by default, the car moves in the Forward direction private MoveDirection current_move_direction = MoveDirection.Forward; // variables for current rotation speed, torque and turn angle private float current_velocity = 0.0f; private float current_torque = 0.0f; private float current_turn_angle = 0.0f; // car physical body private BodyRigid CarBodyRigid = null; private void Init() { // at initialization, get wheel joints and car physical body if (wheel_rl) joint_wheel_rl = wheel_rl.ObjectBody.GetJoint(0) as JointWheel; if (wheel_rr) joint_wheel_rr = wheel_rr.ObjectBody.GetJoint(0) as JointWheel; if (wheel_fl) joint_wheel_fl = wheel_fl.ObjectBody.GetJoint(0) as JointWheel; if (wheel_fr) joint_wheel_fr = wheel_fr.ObjectBody.GetJoint(0) as JointWheel; CarBodyRigid = node.ObjectBodyRigid; } protected virtual void Update() { // get the time it took to render the previous frame in order to be independent from FPS float deltaTime = Game.IFps; // smoothly change the current throttle, brake, and steering position towards the required values current_throttle = MathLib.MoveTowards(current_throttle, target_throttle, throttle_speed * deltaTime); current_brake = MathLib.MoveTowards(current_brake, target_brake, brake_speed * deltaTime); current_wheel = MathLib.MoveTowards(current_wheel, target_wheel, wheel_speed * deltaTime); current_hand_brake = MathLib.MoveTowards(current_hand_brake, target_hand_brake, brake_speed * deltaTime); // enable the brake light node if the brake is activated (value greater than ~zero) if (brake_light != null) brake_light.Enabled = target_brake > MathLib.EPSILON; // the current torque value is calculated as the product of the throttle position and the standard multiplier current_torque = default_torque * current_throttle; // when the throttle is pressed if (current_throttle > MathLib.EPSILON) { // current angular velocity of wheels changes according to acceleration and motion direction current_velocity += deltaTime * MathLib.Lerp(0.0f, acceleration, current_throttle) * (current_move_direction == MoveDirection.Forward ? 1.0f : -1.0f); } else { // otherwise decrease the speed exponentially current_velocity *= MathLib.Exp(-deltaTime); } // calculate the brake force depending on the current brake intensity float damping = MathLib.Lerp(0.0f, brake_damping, current_brake); float rdamping = MathLib.Lerp(0.0f, hand_brake_damping, current_hand_brake); // apply braking for all wheels, hand brake is also applied for the rear wheels joint_wheel_fl.AngularDamping = damping; joint_wheel_fr.AngularDamping = damping; joint_wheel_rl.AngularDamping = MathLib.Max(damping, rdamping); joint_wheel_rr.AngularDamping = MathLib.Max(damping, rdamping); // calculate the current angular velocity and angle of rotation, limited by the extreme values current_velocity = MathLib.Clamp(current_velocity, -max_velocity, max_velocity); current_turn_angle = MathLib.Lerp(-max_turn_angle, max_turn_angle, MathLib.Clamp(0.5f + current_wheel * 0.5f, 0.0f,1.0f)); // simulate differential for the front axle: the wheels should turn by different angles float angle_0 = current_turn_angle; float angle_1 = current_turn_angle; if (MathLib.Abs(current_turn_angle) > MathLib.EPSILON) { float radius = car_base / MathLib.Tan(current_turn_angle * MathLib.DEG2RAD); float radius_0 = radius - car_width * 0.5f; float radius_1 = radius + car_width * 0.5f; angle_0 = MathLib.Atan(car_base / radius_0) * MathLib.RAD2DEG; angle_1 = MathLib.Atan(car_base / radius_1) * MathLib.RAD2DEG; } // apply rotation for both front wheels using the rotation matrix along the Z axis joint_wheel_fr.Axis10 = MathLib.RotateZ(angle_1).GetColumn3(0); joint_wheel_fl.Axis10 = MathLib.RotateZ(angle_0).GetColumn3(0); } // it is important to change the parameters of physical objects in the UpdatePhysics method private void UpdatePhysics() { // apply the calculated values of wheels angular velocity and torque // all 4 wheels have a 'motor', i.e. the car is all-wheel drive joint_wheel_fl.AngularVelocity = current_velocity; joint_wheel_fr.AngularVelocity = current_velocity; joint_wheel_fl.AngularTorque = current_torque; joint_wheel_fr.AngularTorque = current_torque; joint_wheel_rl.AngularVelocity = current_velocity; joint_wheel_rr.AngularVelocity = current_velocity; joint_wheel_rl.AngularTorque = current_torque; joint_wheel_rr.AngularTorque = current_torque; } // add methods to control the car: throttle, brake, steering wheel turning and hand brake protected void SetThrottle(float value) { target_throttle = MathLib.Clamp(value, 0.0f, 1.0f); } protected void SetBrake(float value) { target_brake = MathLib.Clamp(value, 0.0f, 1.0f); } protected void SetWheelPosition(float value) { target_wheel = MathLib.Clamp(value, -1.0f, 1.0f); } protected void SetHandBrake(float value) { target_hand_brake = MathLib.Clamp(value, -1.0f, 1.0f); } // method for changing the driving mode, it also controls the reverse light protected void SetMoveDirection(MoveDirection value) { if (current_move_direction == value) return; current_velocity = 0.0f; current_move_direction = value; if (reverse_light != null) reverse_light.Enabled = current_move_direction == MoveDirection.Reverse; } protected MoveDirection CurrentMoveDirection { get { return current_move_direction; } } // method for the instant car relocation, returns the car to the initial position public void Reset(mat4 transform) { node.WorldTransform = transform; node.ObjectBodyRigid.LinearVelocity = vec3.ZERO; node.ObjectBodyRigid.AngularVelocity = vec3.ZERO; current_velocity = 0.0f; } // get speed immediately in km/h public float Speed { get { return CarBodyRigid.LinearVelocity.Length * 3.6f; } } } A similar third error: Cannot implicitly convert type 'Unigine.dvec3' to 'Unigine.vec3' is also occurring in the Track class at the GetPoint() method: using System; using System.Collections; using System.Collections.Generic; using Unigine; #region Math Variables #if UNIGINE_DOUBLE using Vec3 = Unigine.dvec3; #else using Vec3 = Unigine.vec3; #endif #endregion [Component(PropertyGuid = "7c980256a5c63bcd35202e6015a5ea87487c3357")] public class Track : Component { // list of the track checkpoints private CheckPoint[] points = null; private int[] current_track = null; // index of the current point private int current_point = -1; // callbacks for finishing the track and passing a checkpoint private Action track_end_handler = null; private Action check_point_handler = null; // method called from the checkpoint component called on the player's passing private void OnCarEnter(Car car) { points[current_track[current_point]].SetEnabled(false); current_point++; if (current_point < NumPoints) { points[current_track[current_point]].SetEnabled(true); check_point_handler?.Invoke(); } else { current_point = -1; track_end_handler?.Invoke(); } } // list of checkpoints is built from children with the corresponding component assigned [Method(Order = 1)] private void Init() { points = GetComponentsInChildren<CheckPoint>(node); current_track = new int[points.Length]; for (int i = 0; i < points.Length; i++) { points[i].SetEnterEventHandler(OnCarEnter); current_track[i] = i; } } private void Shutdown() { points = null; current_track = null; current_point = -1; track_end_handler = null; check_point_handler = null; } // each new route is created by shuffling the checkpoint list public void Shuffle() { if (current_point >= 0 && current_point < NumPoints) points[current_track[current_point]].SetEnabled(false); for (int i = current_track.Length - 1; i >= 1; i--) { int j = MathLib.ToInt(MathLib.RandInt(0, i + 1)); int tmp = current_track[j]; current_track[j] = current_track[i]; current_track[i] = tmp; } current_point = 0; points[current_track[current_point]].SetEnabled(true); } public void Restart() { if (current_point >= 0 && current_point < NumPoints) points[current_track[current_point]].SetEnabled(false); current_point = 0; points[current_track[current_point]].SetEnabled(true); } public void SetTrackEndEventHandler(Action handler) { track_end_handler = handler; } public void SetCheckPointEventHandler(Action handler) { check_point_handler = handler; } public int NumPoints { get { return points.Length; } } public vec3 GetPoint(int num) { return points[num].node.WorldPosition; } // the track length obtained by adding the distances between the checkpoints and the starting position public double GetLength(Vec3 start_position) { double result = MathLib.Length(GetPoint(0) - start_position); for(int i = 1; i < NumPoints; i++) { result += MathLib.Length(GetPoint(current_track[i - 1]) - GetPoint(current_track[i])); } return result; } } All code was copy and pasted unmodified from the tutorial. Any help would be appreciated. Edited Friday at 05:38 AM by webnetweaver Link to comment
fox Posted Friday at 08:00 AM Share Posted Friday at 08:00 AM Oh, I see! There are a couple of typos in the initial code. 1) Track.cs component : The return type of the GetPoint() method should be changed to Vec3 instead of vec3: // ... public Vec3 GetPoint(int num) // <-- return type should be Vec3 { return points[num].node.WorldPosition; } // ... 2) Car.cs component : The argument type of the Reset() method should be changed to Mat4 instead of mat4 and a missing definition block for math variables should be added. So, your Car.cs component should look like this: using System; using System.Collections; using System.Collections.Generic; using Unigine; // <--- BLOCK BEGIN #region Math Variables #if UNIGINE_DOUBLE using Mat4 = Unigine.dmat4; #else using Mat4 = Unigine.mat4; #endif #endregion // <--- BLOCK END [Component(PropertyGuid = "b2228d2ad80c5790407b03d47df0295fb3ed433b")] public class Car : Component { // define two modes of movement: forward and reverse protected enum MoveDirection { Forward, Reverse, } // vehicle parameters: acceleration, maximum speed, and wheel turning angle, torque public float acceleration = 50.0f; public float max_velocity = 90.0f; private float max_turn_angle = 30.0f; public float default_torque = 5.0f; // car body length and width public float car_base = 3.0f; public float car_width = 2.0f; // speed of accelerating, braking, and turning public float throttle_speed = 2.0f; public float brake_speed = 1.2f; public float wheel_speed = 2.0f; // service and hand brake force public float brake_damping = 8.0f; public float hand_brake_damping = 30.0f; // references to wheel nodes public Node wheel_fl = null; public Node wheel_fr = null; public Node wheel_rl = null; public Node wheel_rr = null; // references to light nodes: brake and reverse light public Node brake_light = null; public Node reverse_light = null; // wheel joints private JointWheel joint_wheel_fl = null; private JointWheel joint_wheel_fr = null; private JointWheel joint_wheel_rl = null; private JointWheel joint_wheel_rr = null; // define the desired and current values for throttle, brake, steering wheel and hand brake private float target_throttle = 0.0f; private float target_brake = 0.0f; private float target_wheel = 0.0f; private float target_hand_brake = 0.0f; private float current_throttle = 0.0f; private float current_brake = 0.0f; private float current_wheel = 0.0f; private float current_hand_brake = 0.0f; // by default, the car moves in the Forward direction private MoveDirection current_move_direction = MoveDirection.Forward; // variables for current rotation speed, torque and turn angle private float current_velocity = 0.0f; private float current_torque = 0.0f; private float current_turn_angle = 0.0f; // car physical body private BodyRigid CarBodyRigid = null; private void Init() { // at initialization, get wheel joints and car physical body if (wheel_rl) joint_wheel_rl = wheel_rl.ObjectBody.GetJoint(0) as JointWheel; if (wheel_rr) joint_wheel_rr = wheel_rr.ObjectBody.GetJoint(0) as JointWheel; if (wheel_fl) joint_wheel_fl = wheel_fl.ObjectBody.GetJoint(0) as JointWheel; if (wheel_fr) joint_wheel_fr = wheel_fr.ObjectBody.GetJoint(0) as JointWheel; CarBodyRigid = node.ObjectBodyRigid; } protected virtual void Update() { // get the time it took to render the previous frame in order to be independent from FPS float deltaTime = Game.IFps; // smoothly change the current throttle, brake, and steering position towards the required values current_throttle = MathLib.MoveTowards(current_throttle, target_throttle, throttle_speed * deltaTime); current_brake = MathLib.MoveTowards(current_brake, target_brake, brake_speed * deltaTime); current_wheel = MathLib.MoveTowards(current_wheel, target_wheel, wheel_speed * deltaTime); current_hand_brake = MathLib.MoveTowards(current_hand_brake, target_hand_brake, brake_speed * deltaTime); // enable the brake light node if the brake is activated (value greater than ~zero) if (brake_light != null) brake_light.Enabled = target_brake > MathLib.EPSILON; // the current torque value is calculated as the product of the throttle position and the standard multiplier current_torque = default_torque * current_throttle; // when the throttle is pressed if (current_throttle > MathLib.EPSILON) { // current angular velocity of wheels changes according to acceleration and motion direction current_velocity += deltaTime * MathLib.Lerp(0.0f, acceleration, current_throttle) * (current_move_direction == MoveDirection.Forward ? 1.0f : -1.0f); } else { // otherwise decrease the speed exponentially current_velocity *= MathLib.Exp(-deltaTime); } // calculate the brake force depending on the current brake intensity float damping = MathLib.Lerp(0.0f, brake_damping, current_brake); float rdamping = MathLib.Lerp(0.0f, hand_brake_damping, current_hand_brake); // apply braking for all wheels, hand brake is also applied for the rear wheels joint_wheel_fl.AngularDamping = damping; joint_wheel_fr.AngularDamping = damping; joint_wheel_rl.AngularDamping = MathLib.Max(damping, rdamping); joint_wheel_rr.AngularDamping = MathLib.Max(damping, rdamping); // calculate the current angular velocity and angle of rotation, limited by the extreme values current_velocity = MathLib.Clamp(current_velocity, -max_velocity, max_velocity); current_turn_angle = MathLib.Lerp(-max_turn_angle, max_turn_angle, MathLib.Clamp(0.5f + current_wheel * 0.5f, 0.0f,1.0f)); // simulate differential for the front axle: the wheels should turn by different angles float angle_0 = current_turn_angle; float angle_1 = current_turn_angle; if (MathLib.Abs(current_turn_angle) > MathLib.EPSILON) { float radius = car_base / MathLib.Tan(current_turn_angle * MathLib.DEG2RAD); float radius_0 = radius - car_width * 0.5f; float radius_1 = radius + car_width * 0.5f; angle_0 = MathLib.Atan(car_base / radius_0) * MathLib.RAD2DEG; angle_1 = MathLib.Atan(car_base / radius_1) * MathLib.RAD2DEG; } // apply rotation for both front wheels using the rotation matrix along the Z axis joint_wheel_fr.Axis10 = MathLib.RotateZ(angle_1).GetColumn3(0); joint_wheel_fl.Axis10 = MathLib.RotateZ(angle_0).GetColumn3(0); } // it is important to change the parameters of physical objects in the UpdatePhysics method private void UpdatePhysics() { // apply the calculated values of wheels angular velocity and torque // all 4 wheels have a 'motor', i.e. the car is all-wheel drive joint_wheel_fl.AngularVelocity = current_velocity; joint_wheel_fr.AngularVelocity = current_velocity; joint_wheel_fl.AngularTorque = current_torque; joint_wheel_fr.AngularTorque = current_torque; joint_wheel_rl.AngularVelocity = current_velocity; joint_wheel_rr.AngularVelocity = current_velocity; joint_wheel_rl.AngularTorque = current_torque; joint_wheel_rr.AngularTorque = current_torque; } // add methods to control the car: throttle, brake, steering wheel turning and hand brake protected void SetThrottle(float value) { target_throttle = MathLib.Clamp(value, 0.0f, 1.0f); } protected void SetBrake(float value) { target_brake = MathLib.Clamp(value, 0.0f, 1.0f); } protected void SetWheelPosition(float value) { target_wheel = MathLib.Clamp(value, -1.0f, 1.0f); } protected void SetHandBrake(float value) { target_hand_brake = MathLib.Clamp(value, -1.0f, 1.0f); } // method for changing the driving mode, it also controls the reverse light protected void SetMoveDirection(MoveDirection value) { if (current_move_direction == value) return; current_velocity = 0.0f; current_move_direction = value; if (reverse_light != null) reverse_light.Enabled = current_move_direction == MoveDirection.Reverse; } protected MoveDirection CurrentMoveDirection { get { return current_move_direction; } } // method for the instant car relocation, returns the car to the initial position public void Reset(Mat4 transform) //<-- argument type should be Mat4 { node.WorldTransform = transform; node.ObjectBodyRigid.LinearVelocity = vec3.ZERO; node.ObjectBodyRigid.AngularVelocity = vec3.ZERO; current_velocity = 0.0f; } // get speed immediately in km/h public float Speed { get { return CarBodyRigid.LinearVelocity.Length * 3.6f; } } } This should help! Snippets are updated, sorry for the inconvenience caused! Thanks! 1 Link to comment
Recommended Posts