From c21e4db3ea4c91b2ce40223a9faca9a6934d128d Mon Sep 17 00:00:00 2001 From: copygirl Date: Sat, 23 Dec 2023 13:54:02 +0100 Subject: [PATCH] Groundwork for multiplayer - Add IsLocal property to Player - Disable some functionality if local - Tweaks to movement and camera controller - Let players push each other - Add a fake "remote" player for testing - Undo the IInitalizable silliness --- player/AnimationController.cs | 121 +++++++++++++++++++--------------- player/CameraController.cs | 18 ++++- player/MovementController.cs | 48 +++++++++----- player/PickupController.cs | 10 ++- player/Player.cs | 13 +--- player/PushbackArea.cs | 23 +++++++ player/player.tscn | 67 +++++++++++-------- scenes/warehouse.tscn | 4 ++ 8 files changed, 192 insertions(+), 112 deletions(-) create mode 100644 player/PushbackArea.cs diff --git a/player/AnimationController.cs b/player/AnimationController.cs index 53b899c..9fcd4fa 100644 --- a/player/AnimationController.cs +++ b/player/AnimationController.cs @@ -1,4 +1,4 @@ -public partial class AnimationController : Node3D, IInitalizable +public partial class AnimationController : Node3D { [Export] public Skeleton3D Skeleton { get; set; } [Export] public BoneAttachment3D RootBone { get; set; } @@ -17,11 +17,9 @@ public partial class AnimationController : Node3D, IInitalizable AnimationTree _animTree; Animation _walkForwardAnim; Animation _walkBackwardAnim; - public void Initialize(Player player) + public override void _Ready() { - _player = player; - _cameraDefaultTransform = _player.Camera.Camera.Transform; - + _player = GetParent(); _animTree = GetNode("AnimationTree"); _walkForwardAnim = _animTree.GetAnimation("walk_forward"); _walkBackwardAnim = _animTree.GetAnimation("walk_backward"); @@ -45,7 +43,8 @@ public partial class AnimationController : Node3D, IInitalizable { foreach (var bone in _bones.Values) bone.Transform = Skeleton.GetBonePose(bone.BoneIdx); - _player.Camera.Camera.Transform = _cameraDefaultTransform; + if (_player.Camera.Camera is Camera3D camera) + camera.Transform = _player.Camera.DefaultTransform; } void HandleTurning(double delta) @@ -55,8 +54,10 @@ public partial class AnimationController : Node3D, IInitalizable const float TurnSpeed = 6.0f; var yaw = _player.Camera.CurrentYaw; // Camera yaw relative to player yaw. - var isMoving = _player.Movement.RealMoveSpeed > 0.01f; - _isTurning = isMoving || (Abs(yaw) > DegToRad(TurnBegin)); + + var movement = _player.Movement; + var isWalking = movement.LocalMoveVector.Length() > movement.MaxSpeed / 4; + _isTurning = isWalking || (Abs(yaw) > DegToRad(TurnBegin)); if (_isTurning) { var yawDelta = Sign(yaw) * Min(Abs(yaw), Abs(yaw) * TurnSpeed * (float)delta); @@ -70,56 +71,62 @@ public partial class AnimationController : Node3D, IInitalizable void HandleLookingAnimation(double delta) { + var camera = _player.Camera.Camera; + var pitch = _player.Camera.CurrentPitch; + var yaw = _player.Camera.CurrentYaw; + const float PitchFactorLowerBody = 0.05f; const float PitchFactorUpperBody = 0.20f; - const float PitchFactorNeck = 0.25f; - const float PitchFactorHead = 0.35f; - - var pitch = _player.Camera.CurrentPitch; - _bones["LowerBody"].RotateX(pitch * PitchFactorLowerBody); - _bones["UpperBody"].RotateX(-pitch * PitchFactorUpperBody); - _bones["Neck"].RotateX(-pitch * PitchFactorNeck); - _bones["Head"].RotateX(-pitch * PitchFactorHead); - _bones["UpperArm_L"].RotateX(pitch * (PitchFactorLowerBody + PitchFactorUpperBody) / 2); - _bones["UpperArm_R"].RotateX(pitch * (PitchFactorLowerBody + PitchFactorUpperBody) / 2); - _player.Camera.Camera.RotateX(pitch * (1 - PitchFactorLowerBody - PitchFactorUpperBody - PitchFactorNeck - PitchFactorHead)); + const float PitchFactorNeck = 0.25f; + const float PitchFactorHead = 0.35f; + + _bones["LowerBody" ].RotateX( pitch * PitchFactorLowerBody); + _bones["UpperBody" ].RotateX(-pitch * PitchFactorUpperBody); + _bones["Neck" ].RotateX(-pitch * PitchFactorNeck); + _bones["Head" ].RotateX(-pitch * PitchFactorHead); + _bones["UpperArm_L"].RotateX( pitch * (PitchFactorLowerBody + PitchFactorUpperBody) / 2); + _bones["UpperArm_R"].RotateX( pitch * (PitchFactorLowerBody + PitchFactorUpperBody) / 2); + camera?.RotateX(pitch * (1 - PitchFactorLowerBody - PitchFactorUpperBody - PitchFactorNeck - PitchFactorHead)); const float YawFactorLowerBody = 0.06f; const float YawFactorUpperBody = 0.18f; - const float YawFactorNeck = 0.2f; - const float YawFactorHead = 0.3f; + const float YawFactorNeck = 0.2f; + const float YawFactorHead = 0.3f; - var yaw = _player.Camera.CurrentYaw; _bones["LowerBody"].GlobalRotate(Vector3.Up, yaw * YawFactorLowerBody); _bones["UpperBody"].GlobalRotate(Vector3.Up, yaw * YawFactorUpperBody); - _bones["Neck"].GlobalRotate(Vector3.Up, yaw * YawFactorNeck); - _bones["Head"].GlobalRotate(Vector3.Up, yaw * YawFactorHead); - _player.Camera.Camera.GlobalRotate(Vector3.Up, yaw * (1 - YawFactorLowerBody - YawFactorUpperBody - YawFactorNeck - YawFactorHead)); - - // How much of the "ideal" camera rotation (rather than animation rotation) should be applied. - const float CameraFactorIdealPitch = 0.7f; - const float CameraFactorIdealYaw = 0.8f; - const float CameraFactorIdealRoll = 0.9f; - - var global_yaw = _player.Rotation.Y + yaw; - var cameraRotation = _player.Camera.Camera.GlobalRotation; - cameraRotation.X = LerpAngle(cameraRotation.X, pitch, CameraFactorIdealPitch); - cameraRotation.Y = LerpAngle(cameraRotation.Y, global_yaw, CameraFactorIdealYaw); - cameraRotation.Z = LerpAngle(cameraRotation.Z, 0, CameraFactorIdealRoll); - _player.Camera.Camera.GlobalRotation = cameraRotation; + _bones["Neck" ].GlobalRotate(Vector3.Up, yaw * YawFactorNeck); + _bones["Head" ].GlobalRotate(Vector3.Up, yaw * YawFactorHead); + camera?.GlobalRotate(Vector3.Up, yaw * (1 - YawFactorLowerBody - YawFactorUpperBody - YawFactorNeck - YawFactorHead)); + + if (camera != null) { + // How much of the "ideal" camera rotation (rather than animation rotation) should be applied. + const float CameraFactorIdealPitch = 0.7f; + const float CameraFactorIdealYaw = 0.8f; + const float CameraFactorIdealRoll = 0.9f; + + var globalYaw = yaw + _player.Rotation.Y; + var rot = camera.GlobalRotation; + // FIXME: This doesn't apply correctly when looking up or down. + rot.X = LerpAngle(rot.X, pitch, CameraFactorIdealPitch); + rot.Y = LerpAngle(rot.Y, globalYaw, CameraFactorIdealYaw); + rot.Z = LerpAngle(rot.Z, 0, CameraFactorIdealRoll); + camera.GlobalRotation = rot; + } } void HandleWalkingAnimation(double delta) { - var input = Input.GetVector("move_strafe_left", "move_strafe_right", "move_forward", "move_back"); - var isOnFloor = _player.Movement.TimeSinceOnFloor < 0.25f; - var isMoving = _player.Movement.RealMoveSpeed > 0.01f; - var isMovingForward = input.Y <= 0; + const float ForwardAngle = 95.0f; + + var movement = _player.Movement; + var localAngle = movement.LocalMoveAngle; + var isOnFloor = movement.TimeSinceOnFloor < 0.25f; + var isMovingForward = Abs(localAngle) <= DegToRad(ForwardAngle); - var walkState = (isOnFloor && isMoving) ? "move" : "idle"; + var walkState = (isOnFloor && movement.IsMoving) ? "move" : "idle"; var walkDirection = isMovingForward ? "forward" : "backward"; - var walkSpeed = _player.Movement.RealMoveSpeed / _player.Movement.MaxSpeed; - var targetBodyYaw = -(isMovingForward ? Vector2.Up : Vector2.Down).AngleTo(input); + var walkSpeed = movement.LocalMoveVector.Length() / movement.MaxSpeed; _animTree.Set("parameters/walk_state/transition_request", walkState); _animTree.Set("parameters/walk_direction/transition_request", walkDirection); @@ -127,15 +134,21 @@ public partial class AnimationController : Node3D, IInitalizable var prevWalkSpeed = (float)_animTree.Get("parameters/walk_speed/blend_amount"); _animTree.Set("parameters/walk_speed/blend_amount", Lerp(prevWalkSpeed, walkSpeed, 10 * (float)delta)); - const float YAW_FACTOR_LOWER_BODY = 0.25f; - const float YAW_FACTOR_UPPER_BODY = 0.25f; - const float YAW_FACTOR_NECK = 0.50f; - - _bodyYaw += (targetBodyYaw - _bodyYaw) * (float)delta * 6; - - _bones["Root"].GlobalRotate(Vector3.Up, _bodyYaw); - _bones["LowerBody"].GlobalRotate(Vector3.Up, -_bodyYaw * YAW_FACTOR_LOWER_BODY); - _bones["UpperBody"].GlobalRotate(Vector3.Up, -_bodyYaw * YAW_FACTOR_UPPER_BODY); - _bones["Neck"].GlobalRotate(Vector3.Up, -_bodyYaw * YAW_FACTOR_NECK); + const float YawFactorLowerBody = 0.15f; + const float YawFactorUpperBody = 0.20f; + const float YawFactorNeck = 0.45f; + + if (movement.IsMoving) { + var targetBodyYaw = localAngle; + if (!isMovingForward) targetBodyYaw -= Sign(localAngle) * Tau / 2; + _bodyYaw += (targetBodyYaw - _bodyYaw) * (float)delta * 6; + } else + _bodyYaw -= _bodyYaw * (float)delta * 2; + + // FIXME: Something is causing `_bodyYaw` to jitter when a player is pushed against an object. + _bones["Root" ].GlobalRotate(Vector3.Up, _bodyYaw * (YawFactorLowerBody + YawFactorUpperBody + YawFactorNeck)); + _bones["LowerBody"].GlobalRotate(Vector3.Up, -_bodyYaw * YawFactorLowerBody); + _bones["UpperBody"].GlobalRotate(Vector3.Up, -_bodyYaw * YawFactorUpperBody); + _bones["Neck" ].GlobalRotate(Vector3.Up, -_bodyYaw * YawFactorNeck); } } diff --git a/player/CameraController.cs b/player/CameraController.cs index 48b2a6b..7642a98 100644 --- a/player/CameraController.cs +++ b/player/CameraController.cs @@ -1,18 +1,34 @@ public partial class CameraController : Node { - [Export] public Camera3D Camera { get; set; } + [Export] public Camera3D Camera { get; set; } // Will be `null` for remote players. [Export] public Vector2 MouseSensitivity { get; set; } = new(0.2f, 0.2f); // Degrees per pixel. [Export] public float PitchMinimum { get; set; } = -85; [Export] public float PitchMaximum { get; set; } = 85; + public Transform3D DefaultTransform { get; private set; } + public float CurrentPitch { get; set; } public float CurrentYaw { get; set; } public static bool IsMouseCaptured => Input.MouseMode == Input.MouseModeEnum.Captured; + Player _player; + public override void _Ready() + { + _player = GetParent(); + + if (_player.IsLocal) { + DefaultTransform = Camera.Transform; + } else { + Camera.QueueFree(); + Camera = null; + } + } + public override void _UnhandledInput(InputEvent @event) { + if (!_player.IsLocal) return; if (@event.IsActionPressed("ui_cancel") && IsMouseCaptured) { // When escape is pressed, release the mouse. Input.MouseMode = Input.MouseModeEnum.Visible; diff --git a/player/MovementController.cs b/player/MovementController.cs index 6caa122..04b1118 100644 --- a/player/MovementController.cs +++ b/player/MovementController.cs @@ -1,4 +1,4 @@ -public partial class MovementController : Node, IInitalizable +public partial class MovementController : Node { [ExportGroup("Movement")] [Export] public float Acceleration { get; set; } = 4.0f; @@ -8,19 +8,30 @@ public partial class MovementController : Node, IInitalizable public float Gravity { get; } = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); [ExportGroup("Jumping")] - [Export] public float JumpVelocity { get; set; } = 4.0f; - [Export] public float JumpEarlyTime { get; set; } = 0.0f; // Time (in seconds) after pressing the jump button a jump may occur late. - [Export] public float JumpCoyoteTime { get; set; } = 0.0f; // Time (in seconds) after leaving a jumpable surface when a jump may still occur. + [Export] public float JumpVelocity { get; set; } = 4.0f; + /// Time (in seconds) after pressing the jump button a jump may occur late. + [Export] public float JumpEarlyTime { get; set; } = 0.0f; + /// Time (in seconds) after leaving a jumpable surface when a jump may still occur. + [Export] public float JumpCoyoteTime { get; set; } = 0.0f; - public float RealMoveSpeed { get; private set; } public bool IsSprinting { get; private set; } + /// The raw input movement vector with a maximum length of 1. + public Vector2 InputVector { get; private set; } + + public bool IsMoving => LocalMoveVector.Length() > 0.01f; + /// The actual amount the player is moving, relative to the world. Y is always 0. + public Vector3 GlobalMoveVector { get; private set; } + /// The actual amount the player is moving, relative to the player's viewpoint. Y is always 0. + public Vector3 LocalMoveVector { get; private set; } + /// + public float LocalMoveAngle { get; private set; } public float TimeSinceJumpPressed { get; private set; } = float.PositiveInfinity; public float TimeSinceOnFloor { get; private set; } = float.PositiveInfinity; Player _player; - public void Initialize(Player player) - => _player = player; + public override void _Ready() + => _player = GetParent(); public override void _UnhandledInput(InputEvent @event) { @@ -30,23 +41,23 @@ public partial class MovementController : Node, IInitalizable public override void _PhysicsProcess(double delta) { + var velocity = _player.Velocity; + // velocity.Y -= Gravity * (float)delta; // TODO: Gravity. + // Get the (normalized) movement vector from the current input. - var input = Input.GetVector("move_strafe_left", "move_strafe_right", "move_forward", "move_back"); + InputVector = _player.IsLocal + ? Input.GetVector("move_strafe_left", "move_strafe_right", "move_forward", "move_back") + : Vector2.Zero; - var velocity = _player.Velocity; var horVelocity = velocity with { Y = 0 }; - - // TODO: Gravity. - // velocity.Y -= Gravity * (float)delta; - var basis = _player.Basis.Rotated(Vector3.Up, _player.Camera.CurrentYaw); - var target = basis * new Vector3(input.X, 0, input.Y) * MaxSpeed; + var target = basis * new Vector3(InputVector.X, 0, InputVector.Y) * MaxSpeed; var isMoving = target.Dot(horVelocity) > 0.0f; var isOnFloor = true; // _player.IsOnFloor(); var accel = isMoving ? Acceleration - : isOnFloor ? FrictionFloor - : FrictionAir; + : isOnFloor ? FrictionFloor + : FrictionAir; if (IsSprinting) { target *= 5; @@ -68,6 +79,9 @@ public partial class MovementController : Node, IInitalizable _player.Velocity = velocity; _player.MoveAndSlide(); - RealMoveSpeed = (_player.Velocity with { Y = 0 }).Length(); + // TODO: Very simplified, but works for now. + GlobalMoveVector = _player.Velocity with { Y = 0 }; + LocalMoveVector = _player.Basis.Inverse() * GlobalMoveVector; + LocalMoveAngle = Vector3.Forward.SignedAngleTo(LocalMoveVector, Vector3.Up); } } diff --git a/player/PickupController.cs b/player/PickupController.cs index 3839199..8b1388e 100644 --- a/player/PickupController.cs +++ b/player/PickupController.cs @@ -1,4 +1,4 @@ -public partial class PickupController : Node3D, IInitalizable +public partial class PickupController : Node3D { public Item CurrentItem { get; private set; } public bool IsCurrentItemHeld { get; private set; } @@ -7,16 +7,19 @@ public partial class PickupController : Node3D, IInitalizable [Export] public Camera3D Camera { get; set; } [Export] public float PickupDistance { get; set; } = 2.0f; + Player _player; Node3D _world; - public void Initialize(Player player) + public override void _Ready() { + _player = GetParent(); // TODO: Find a better way to find the world. // For now we just use the parent of the `Player` object. - _world = player.GetParent(); + _world = _player.GetParent(); } public override void _UnhandledInput(InputEvent @event) { + if (!_player.IsLocal) return; EnsureCurrentItemValid(); if (CurrentItem == null) return; @@ -55,6 +58,7 @@ public partial class PickupController : Node3D, IInitalizable public override void _PhysicsProcess(double delta) { + if (!_player.IsLocal) return; EnsureCurrentItemValid(); if (IsCurrentItemHeld) { diff --git a/player/Player.cs b/player/Player.cs index 62703c2..5cc7abb 100644 --- a/player/Player.cs +++ b/player/Player.cs @@ -1,24 +1,17 @@ public partial class Player : CharacterBody3D { + [Export] public bool IsLocal { get; set; } = true; + public MovementController Movement { get; private set; } public CameraController Camera { get; private set; } public AnimationController Animation { get; private set; } public PickupController Pickup { get; private set; } - public override void _Ready() + public override void _EnterTree() { Movement = GetNode("MovementController"); Camera = GetNode("CameraController"); Animation = GetNode("AnimationController"); Pickup = GetNode("PickupController"); - - foreach (var child in GetChildren()) - if (child is IInitalizable init) - init.Initialize(this); } } - -public interface IInitalizable -{ - void Initialize(T param); -} diff --git a/player/PushbackArea.cs b/player/PushbackArea.cs new file mode 100644 index 0000000..e40de6d --- /dev/null +++ b/player/PushbackArea.cs @@ -0,0 +1,23 @@ +public partial class PushbackArea : Area3D +{ + [Export] public float PushForce { get; set; } = 24.0f; + + Player _player; + float _radius; + public override void _Ready() + { + _player = GetParent(); + _radius = ((CapsuleShape3D)GetNode("CollisionShape3D").Shape).Radius; + } + + public override void _PhysicsProcess(double delta) + { + foreach (var area in GetOverlappingAreas()) { + var offset = (GlobalPosition - area.GlobalPosition) with { Y = 0 }; + var directions = offset.Normalized(); + var distance = offset.Length() / (_radius * 2); + var force = (1 - distance) * PushForce * (float)delta; + _player.Velocity += directions * force; + } + } +} diff --git a/player/player.tscn b/player/player.tscn index 0df4e12..d839f10 100644 --- a/player/player.tscn +++ b/player/player.tscn @@ -1,14 +1,19 @@ -[gd_scene load_steps=22 format=3 uid="uid://dmd7w2r8s0x6y"] +[gd_scene load_steps=24 format=3 uid="uid://dmd7w2r8s0x6y"] [ext_resource type="PackedScene" uid="uid://bfh3eqgywr0ul" path="res://assets/models/character.blend" id="1_3qh37"] [ext_resource type="Script" path="res://player/Player.cs" id="1_a0mas"] [ext_resource type="Script" path="res://player/MovementController.cs" id="2_1pst4"] +[ext_resource type="Script" path="res://player/PushbackArea.cs" id="2_almik"] [ext_resource type="Script" path="res://player/PickupController.cs" id="2_ns2pe"] [ext_resource type="Script" path="res://player/CameraController.cs" id="2_r3gna"] [ext_resource type="Script" path="res://player/AnimationController.cs" id="3_5rlwc"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_h1mfd"] -radius = 0.3 +radius = 0.24 +height = 1.5 + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_l8s0f"] +radius = 0.28 height = 1.5 [sub_resource type="Animation" id="Animation_arrr6"] @@ -806,39 +811,47 @@ script = ExtResource("1_a0mas") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("CapsuleShape3D_h1mfd") +[node name="PushbackArea" type="Area3D" parent="."] +collision_layer = 4 +collision_mask = 4 +script = ExtResource("2_almik") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PushbackArea"] +shape = SubResource("CapsuleShape3D_l8s0f") + [node name="Model" parent="." instance=ExtResource("1_3qh37")] transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, -0.75, 0) [node name="Root" type="BoneAttachment3D" parent="Model/Skeleton" index="0"] -transform = Transform3D(-1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0.199954, 0) +transform = Transform3D(-1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0.198674, 0) bone_name = "Root" bone_idx = 2 use_external_skeleton = true external_skeleton = NodePath("../Skeleton3D") [node name="LowerBody" type="BoneAttachment3D" parent="Model/Skeleton/Root"] -transform = Transform3D(-1, -1.45235e-11, 8.74228e-08, 8.71645e-08, 0.0766475, 0.997058, -6.71523e-09, 0.997058, -0.0766476, 0, 0, -0.199593) +transform = Transform3D(-1, -1.80478e-09, 8.74042e-08, 8.71645e-08, 0.0562133, 0.998419, -6.71521e-09, 0.998419, -0.0562134, 0, 0, -0.199593) bone_name = "LowerBody" bone_idx = 3 use_external_skeleton = true external_skeleton = NodePath("../../Skeleton3D") [node name="UpperBody" type="BoneAttachment3D" parent="Model/Skeleton/Root/LowerBody"] -transform = Transform3D(1, -1.0796e-08, 8.67536e-08, 0, 0.992346, 0.123492, -8.74228e-08, -0.123492, 0.992346, 8.88178e-16, 0.154362, 7.45058e-09) +transform = Transform3D(1, -7.15076e-09, 8.71298e-08, 0, 0.996649, 0.0817951, -8.74228e-08, -0.0817951, 0.996649, 0, 0.154362, 0) bone_name = "UpperBody" bone_idx = 4 use_external_skeleton = true external_skeleton = NodePath("../../../Skeleton3D") [node name="Neck" type="BoneAttachment3D" parent="Model/Skeleton/Root/LowerBody/UpperBody"] -transform = Transform3D(1, -8.30499e-17, 1.42109e-14, -1.33227e-15, 0.998891, -0.0470728, 7.10543e-15, 0.0470728, 0.998891, 2.22045e-16, 0.251888, -1.11759e-08) +transform = Transform3D(1, 2.22045e-16, 0, 8.88178e-16, 0.998891, -0.0470728, -7.10543e-15, 0.0470728, 0.998892, 6.66134e-16, 0.251888, 0) bone_name = "Neck" bone_idx = 5 use_external_skeleton = true external_skeleton = NodePath("../../../../Skeleton3D") [node name="Head" type="BoneAttachment3D" parent="Model/Skeleton/Root/LowerBody/UpperBody/Neck"] -transform = Transform3D(-1, 1.13687e-12, 8.74228e-08, 8.74228e-08, 1.31093e-05, 1, -7.10543e-15, 1, -1.32285e-05, -2.22045e-16, 0.101598, 1.86265e-09) +transform = Transform3D(-1, 4.67566e-10, 8.74215e-08, 8.74228e-08, 0.0053482, 0.999986, 0, 0.999986, -0.00534832, 1.11022e-16, 0.101598, 3.72529e-09) bone_name = "Head" bone_idx = 6 use_external_skeleton = true @@ -849,38 +862,38 @@ transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.0 cull_mask = 1 [node name="UpperArm_L" type="BoneAttachment3D" parent="Model/Skeleton/Root/LowerBody/UpperBody"] -transform = Transform3D(-0.939275, 0.343167, -1.43629e-05, -0.342785, -0.938234, -0.0470729, -0.0161673, -0.0442095, 0.998891, 0.0873834, 0.213866, -0.00179178) +transform = Transform3D(-0.949823, 0.312787, -0.000684065, -0.31241, -0.948781, -0.0470616, -0.0153693, -0.0444865, 0.998892, 0.0873834, 0.213866, -0.00179177) bone_name = "UpperArm_L" bone_idx = 7 use_external_skeleton = true external_skeleton = NodePath("../../../../Skeleton3D") [node name="UpperArm_R" type="BoneAttachment3D" parent="Model/Skeleton/Root/LowerBody/UpperBody"] -transform = Transform3D(-0.939275, -0.343167, 1.43629e-05, 0.342785, -0.938234, -0.0470729, 0.0161673, -0.0442095, 0.998891, -0.0873834, 0.213866, -0.00179178) +transform = Transform3D(-0.949823, -0.312787, 0.000684064, 0.31241, -0.948781, -0.0470616, 0.0153693, -0.0444865, 0.998892, -0.0873834, 0.213866, -0.00179177) bone_name = "UpperArm_R" bone_idx = 14 use_external_skeleton = true external_skeleton = NodePath("../../../../Skeleton3D") [node name="Skeleton3D" parent="Model/Skeleton" index="1"] -bones/1/rotation = Quaternion(-0.707263, 2.19513e-18, -2.07659e-18, 0.706951) -bones/2/position = Vector3(0, 0.199954, 0) -bones/3/rotation = Quaternion(2.96951e-08, 0.733706, 0.679468, 3.20762e-08) -bones/4/rotation = Quaternion(-0.0618643, 4.36277e-08, 2.70417e-09, 0.998085) -bones/6/rotation = Quaternion(3.09088e-08, 0.707111, 0.707102, 3.09084e-08) -bones/7/rotation = Quaternion(-0.00410941, -0.0231815, 0.984429, -0.174201) -bones/8/rotation = Quaternion(2.06571e-06, 7.0899e-06, -0.0625704, 0.998041) -bones/9/rotation = Quaternion(-1.49484e-06, -6.92559e-06, -0.0178983, 0.99984) -bones/14/rotation = Quaternion(0.00410941, -0.0231815, 0.984429, 0.174201) -bones/15/rotation = Quaternion(2.06571e-06, -7.08988e-06, 0.0625704, 0.998041) -bones/16/rotation = Quaternion(-1.49484e-06, 6.92559e-06, 0.0178983, 0.99984) -bones/21/rotation = Quaternion(0.00988475, -0.701685, 0.712355, 0.00956142) -bones/22/rotation = Quaternion(0.0133306, 0.00254896, 0.000813956, 0.999908) -bones/23/rotation = Quaternion(-0.000983995, -0.692252, 0.721401, -0.019142) -bones/24/rotation = Quaternion(-0.00988476, -0.701685, 0.712355, -0.00956141) -bones/25/rotation = Quaternion(0.0133306, -0.00254896, -0.000813955, 0.999908) -bones/26/rotation = Quaternion(0.000983995, -0.692252, 0.721401, 0.019142) -bones/28/rotation = Quaternion(-0.707263, 2.19513e-18, -2.07659e-18, 0.706951) +bones/1/rotation = Quaternion(-0.725527, 1.06167e-18, -1.00434e-18, 0.688194) +bones/2/position = Vector3(0, 0.198675, 0) +bones/3/rotation = Quaternion(2.93651e-08, 0.72671, 0.686945, 3.23786e-08) +bones/4/rotation = Quaternion(-0.0409319, 4.36748e-08, 1.78919e-09, 0.999162) +bones/6/rotation = Quaternion(3.09912e-08, 0.708995, 0.705213, 3.08259e-08) +bones/7/rotation = Quaternion(-0.00406577, -0.0231861, 0.987104, -0.158341) +bones/8/rotation = Quaternion(9.74191e-05, 0.000328126, -0.0786104, 0.996905) +bones/9/rotation = Quaternion(-7.20592e-05, -0.0003409, -0.00150931, 0.999999) +bones/14/rotation = Quaternion(0.00406577, -0.0231861, 0.987104, 0.158341) +bones/15/rotation = Quaternion(9.74189e-05, -0.000328126, 0.0786104, 0.996905) +bones/16/rotation = Quaternion(-7.20589e-05, 0.0003409, 0.00150931, 0.999999) +bones/21/rotation = Quaternion(0.0107169, -0.719663, 0.694155, 0.0108845) +bones/22/rotation = Quaternion(0.0628015, 0.00254414, 0.0038346, 0.998015) +bones/23/rotation = Quaternion(-0.00149249, -0.672831, 0.739548, -0.0191091) +bones/24/rotation = Quaternion(-0.0107169, -0.719663, 0.694155, -0.0108845) +bones/25/rotation = Quaternion(0.0628015, -0.00254414, -0.0038346, 0.998015) +bones/26/rotation = Quaternion(0.00149248, -0.672831, 0.739548, 0.0191091) +bones/28/rotation = Quaternion(-0.725527, 1.06167e-18, -1.00434e-18, 0.688194) [node name="MovementController" type="Node" parent="."] script = ExtResource("2_1pst4") diff --git a/scenes/warehouse.tscn b/scenes/warehouse.tscn index aaa6b8c..eac8512 100644 --- a/scenes/warehouse.tscn +++ b/scenes/warehouse.tscn @@ -31,6 +31,10 @@ transform = Transform3D(0.866025, 0, -0.5, 0.25, 0.866025, 0.433013, 0.433013, - [node name="Player" parent="." instance=ExtResource("1_cxvln")] +[node name="OtherPlayer" parent="." instance=ExtResource("1_cxvln")] +transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 2, 0.75, -4) +IsLocal = false + [node name="Crates" type="Node3D" parent="."] [node name="Crate1" parent="Crates" instance=ExtResource("2_j6a20")]