GLXY | A simplified gravity simulator for Android | Game Engine library
kandi X-RAY | GLXY Summary
Support
Quality
Security
License
Reuse
- Draws the background
- Add a point to the trail
- Render the specified trail
- Draws the next set of particles
- Resize the camera
- Load the current Atlas
- Get a texture region by name
- Adds a button to the dialog
- Returns the description for the given setting
- Adds a button to the table
- Dispose the screen
- Pauses the screen
- Resize the screen
- Resume the screen
- Set bottom bar
- Disposes the logo
- Display the stage
- Create the main menu
- Removes all tracked particles
- Handles a keyup event
- Initialize the application
- Render the screen
- Shows the stage
- Disposes resources
- Process the input
- Handle key up
GLXY Key Features
GLXY Examples and Code Snippets
Trending Discussions on Game Engine
Trending Discussions on Game Engine
QUESTION
I'm very new in Unity and Stackowerflow. If i did something wrong, please don't judge me ^^ I used Unity's TPS Controller asset for my game. In first, it worked very well. But then It broke. But i didn't do anything :( (i don't even touch scripts or prefabs). After that, i deleted asset and re-download it but it didnt work again. Here is one example from my broken scene and these are the codes from my controller. Thanks For Any Kind of Help.
Starter Assets Inputusing UnityEngine;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
using UnityEngine.InputSystem;
#endif
namespace StarterAssets
{
public class StarterAssetsInputs : MonoBehaviour
{
[Header("Character Input Values")]
public Vector2 move;
public Vector2 look;
public bool jump;
public bool sprint;
[Header("Movement Settings")]
public bool analogMovement;
#if !UNITY_IOS || !UNITY_ANDROID
[Header("Mouse Cursor Settings")]
public bool cursorLocked = true;
public bool cursorInputForLook = true;
#endif
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
public void OnMove(InputValue value)
{
MoveInput(value.Get());
}
public void OnLook(InputValue value)
{
if(cursorInputForLook)
{
LookInput(value.Get());
}
}
public void OnJump(InputValue value)
{
JumpInput(value.isPressed);
}
public void OnSprint(InputValue value)
{
SprintInput(value.isPressed);
}
#else
// old input sys if we do decide to have it (most likely wont)...
#endif
public void MoveInput(Vector2 newMoveDirection)
{
move = newMoveDirection;
Debug.Log(move.magnitude);
Debug.Log(move.normalized.magnitude);
}
public void LookInput(Vector2 newLookDirection)
{
look = newLookDirection;
}
public void JumpInput(bool newJumpState)
{
jump = newJumpState;
}
public void SprintInput(bool newSprintState)
{
sprint = newSprintState;
}
#if !UNITY_IOS || !UNITY_ANDROID
private void OnApplicationFocus(bool hasFocus)
{
SetCursorState(cursorLocked);
}
private void SetCursorState(bool newState)
{
Cursor.lockState = newState ? CursorLockMode.Locked : CursorLockMode.None;
}
#endif
}
}
using UnityEngine;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
using UnityEngine.InputSystem;
#endif
/* Note: animations are called via the controller for both the character and capsule using animator null checks
*/
namespace StarterAssets
{
[RequireComponent(typeof(CharacterController))]
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
[RequireComponent(typeof(PlayerInput))]
#endif
public class ThirdPersonController : MonoBehaviour
{
[Header("Player")]
[Tooltip("Move speed of the character in m/s")]
public float MoveSpeed = 2.0f;
[Tooltip("Sprint speed of the character in m/s")]
public float SprintSpeed = 5.335f;
[Tooltip("How fast the character turns to face movement direction")]
[Range(0.0f, 0.3f)]
public float RotationSmoothTime = 0.12f;
[Tooltip("Acceleration and deceleration")]
public float SpeedChangeRate = 10.0f;
[Space(10)]
[Tooltip("The height the player can jump")]
public float JumpHeight = 1.2f;
[Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
public float Gravity = -15.0f;
[Space(10)]
[Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
public float JumpTimeout = 0.50f;
[Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
public float FallTimeout = 0.15f;
[Header("Player Grounded")]
[Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
public bool Grounded = true;
[Tooltip("Useful for rough ground")]
public float GroundedOffset = -0.14f;
[Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
public float GroundedRadius = 0.28f;
[Tooltip("What layers the character uses as ground")]
public LayerMask GroundLayers;
[Header("Cinemachine")]
[Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
public GameObject CinemachineCameraTarget;
[Tooltip("How far in degrees can you move the camera up")]
public float TopClamp = 70.0f;
[Tooltip("How far in degrees can you move the camera down")]
public float BottomClamp = -30.0f;
[Tooltip("Additional degress to override the camera. Useful for fine tuning camera position when locked")]
public float CameraAngleOverride = 0.0f;
[Tooltip("For locking the camera position on all axis")]
public bool LockCameraPosition = false;
// cinemachine
private float _cinemachineTargetYaw;
private float _cinemachineTargetPitch;
// player
private float _speed;
private float _animationBlend;
private float _targetRotation = 0.0f;
private float _rotationVelocity;
private float _verticalVelocity;
private float _terminalVelocity = 53.0f;
// timeout deltatime
private float _jumpTimeoutDelta;
private float _fallTimeoutDelta;
// animation IDs
private int _animIDSpeed;
private int _animIDGrounded;
private int _animIDJump;
private int _animIDFreeFall;
private int _animIDMotionSpeed;
private Animator _animator;
private CharacterController _controller;
private StarterAssetsInputs _input;
private GameObject _mainCamera;
private const float _threshold = 0.01f;
private bool _hasAnimator;
private void Awake()
{
// get a reference to our main camera
if (_mainCamera == null)
{
_mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
}
}
private void Start()
{
_hasAnimator = TryGetComponent(out _animator);
_controller = GetComponent();
_input = GetComponent();
AssignAnimationIDs();
// reset our timeouts on start
_jumpTimeoutDelta = JumpTimeout;
_fallTimeoutDelta = FallTimeout;
}
private void Update()
{
_hasAnimator = TryGetComponent(out _animator);
JumpAndGravity();
GroundedCheck();
Move();
}
private void LateUpdate()
{
CameraRotation();
}
private void AssignAnimationIDs()
{
_animIDSpeed = Animator.StringToHash("Speed");
_animIDGrounded = Animator.StringToHash("Grounded");
_animIDJump = Animator.StringToHash("Jump");
_animIDFreeFall = Animator.StringToHash("FreeFall");
_animIDMotionSpeed = Animator.StringToHash("MotionSpeed");
}
private void GroundedCheck()
{
// set sphere position, with offset
Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z);
Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore);
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDGrounded, Grounded);
}
}
private void CameraRotation()
{
// if there is an input and camera position is not fixed
if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition)
{
_cinemachineTargetYaw += _input.look.x * Time.deltaTime;
_cinemachineTargetPitch += _input.look.y * Time.deltaTime;
}
// clamp our rotations so our values are limited 360 degrees
_cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
_cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
// Cinemachine will follow this target
CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride, _cinemachineTargetYaw, 0.0f);
}
private void Move()
{
// set target speed based on move speed, sprint speed and if sprint is pressed
float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
// a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon
// note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is no input, set the target speed to 0
if (_input.move == Vector2.zero) targetSpeed = 0.0f;
// a reference to the players current horizontal velocity
float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
float speedOffset = 0.1f;
float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
// accelerate or decelerate to target speed
if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
{
// creates curved result rather than a linear one giving a more organic speed change
// note T in Lerp is clamped, so we don't need to clamp our speed
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
// round speed to 3 decimal places
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed;
}
_animationBlend = Mathf.Lerp(_animationBlend, targetSpeed, Time.deltaTime * SpeedChangeRate);
// normalise input direction
Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
// note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is a move input rotate player when the player is moving
if (_input.move != Vector2.zero)
{
_targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg + _mainCamera.transform.eulerAngles.y;
float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity, RotationSmoothTime);
// rotate to face input direction relative to camera position
transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
}
Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
// move the player
_controller.Move(targetDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
// update animator if using character
if (_hasAnimator)
{
_animator.SetFloat(_animIDSpeed, _animationBlend);
_animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
}
}
private void JumpAndGravity()
{
if (Grounded)
{
// reset the fall timeout timer
_fallTimeoutDelta = FallTimeout;
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, false);
_animator.SetBool(_animIDFreeFall, false);
}
// stop our velocity dropping infinitely when grounded
if (_verticalVelocity < 0.0f)
{
_verticalVelocity = -2f;
}
// Jump
if (_input.jump && _jumpTimeoutDelta <= 0.0f)
{
// the square root of H * -2 * G = how much velocity needed to reach desired height
_verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, true);
}
}
// jump timeout
if (_jumpTimeoutDelta >= 0.0f)
{
_jumpTimeoutDelta -= Time.deltaTime;
}
}
else
{
// reset the jump timeout timer
_jumpTimeoutDelta = JumpTimeout;
// fall timeout
if (_fallTimeoutDelta >= 0.0f)
{
_fallTimeoutDelta -= Time.deltaTime;
}
else
{
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDFreeFall, true);
}
}
// if we are not grounded, do not jump
_input.jump = false;
}
// apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
if (_verticalVelocity < _terminalVelocity)
{
_verticalVelocity += Gravity * Time.deltaTime;
}
}
private static float ClampAngle(float lfAngle, float lfMin, float lfMax)
{
if (lfAngle < -360f) lfAngle += 360f;
if (lfAngle > 360f) lfAngle -= 360f;
return Mathf.Clamp(lfAngle, lfMin, lfMax);
}
private void OnDrawGizmosSelected()
{
Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
if (Grounded) Gizmos.color = transparentGreen;
else Gizmos.color = transparentRed;
// when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius);
}
}
}
ANSWER
Answered 2022-Apr-08 at 23:22I had the same problem too. I researched a lot of documents about that and finally, I solved this problem. The problem is not about your codes or events or smth else. The problem is related to Unity. I don't know the exact reason for the problem but you can solve it this way: First, go Edit > Project Settings and select Input System Package from the Left tab. And then, change the Update Method with Process Events In Dynamic Update. And that's all! Dynamic update means the usual Update method that you see in the scripts void Update().
ImagesQUESTION
I am learning to program a game engine which is why I followed a tutorial, with that tutorial I have gotten this far and even though my code is identical to theirs (theirs did work in the videos) its not working the way it is meant to. The triangle stays black no matter what. There is not any errors.
Main Program Script:
using System;
using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.Common;
using System.Drawing;
using OpenTK.Graphics.OpenGL4;
using System.IO;
namespace Game_Engine
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
GameWindowSettings gws = GameWindowSettings.Default;
NativeWindowSettings nws = NativeWindowSettings.Default;
gws.IsMultiThreaded = false;
gws.RenderFrequency = 60;
gws.UpdateFrequency = 60;
nws.APIVersion = Version.Parse("4.1.0");
nws.AutoLoadBindings = true;
nws.Size = new Vector2i(1280, 720);
nws.Title = "Horizon";
GameWindow window = new GameWindow(gws, nws);
window.UpdateFrame += (FrameEventArgs args) => {
};
ShaderProgram shaderProgram = new ShaderProgram(){id = 0};
window.Load += () =>
{
Console.WriteLine("Hello");
ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
};
window.RenderFrame += (FrameEventArgs args) =>
{
GL.UseProgram( shaderProgram.id );
GL.ClearColor(1.0f, 0.0f, 0.0f, 0.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f };
float[] color = { 1f, 0, 0, 0, 1f ,0 ,0, 0, 1f };
int vao = GL.GenVertexArray();
int vertices = GL.GenBuffer();
int colors = GL.GenBuffer();
GL.BindVertexArray(vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertices);
GL.BufferData( BufferTarget.ArrayBuffer, verts.Length * sizeof(float), verts, BufferUsageHint.StaticCopy);
GL.EnableVertexAttribArray( 0 );
GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, false, 0, 0 );
GL.BindBuffer(BufferTarget.ArrayBuffer, colors);
GL.BufferData(BufferTarget.ArrayBuffer, color.Length * sizeof(float), color, BufferUsageHint.StaticCopy);
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
GL.DeleteBuffer(vertices);
GL.DeleteBuffer(colors);
GL.DeleteVertexArray( vao );
window.SwapBuffers();
};
window.Run();
}
private static Shader LoadShader(string shaderLocation, ShaderType type)
{
int shaderId = GL.CreateShader( type );
GL.ShaderSource( shaderId, File.ReadAllText( shaderLocation ) );
GL.CompileShader( shaderId );
string infoLog = GL.GetShaderInfoLog( shaderId );
if (!string.IsNullOrEmpty(infoLog))
{
throw new Exception(infoLog);
}
return new Shader() { id = shaderId };
}
private static ShaderProgram LoadShaderProgram( string vertextShaderLocation, string fragmentShaderLocation)
{
int shaderProgramId = GL.CreateProgram();
Shader vertextShader = LoadShader(vertextShaderLocation, ShaderType.VertexShader);
Shader fragmentShader = LoadShader(fragmentShaderLocation, ShaderType.FragmentShader);
GL.AttachShader(shaderProgramId, vertextShader.id);
GL.AttachShader(shaderProgramId, fragmentShader.id);
GL.LinkProgram(shaderProgramId);
GL.DetachShader(shaderProgramId, vertextShader.id);
GL.DetachShader(shaderProgramId, fragmentShader.id);
GL.DeleteShader(vertextShader.id);
GL.DeleteShader(fragmentShader.id);
string infoLog = GL.GetProgramInfoLog(shaderProgramId);
if (!string.IsNullOrEmpty(infoLog))
{
throw new Exception(infoLog);
}
return new ShaderProgram() { id = shaderProgramId };
}
public struct Shader
{
public int id;
}
public struct ShaderProgram
{
public int id;
}
}
}
Fragment Shader (in glsl):
#version 400
in vec3 color_in;
out vec4 color_out;
void main(){
color_out = vec4(color_in.r, color_in.g, color_in.b, 1);
}
VertexShader (in glsl):
#version 330
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vColors;
out vec3 color_in;
void main() {
color_in = vColors;
gl_Position = vec4( vPosition, 1.0 );
}
I have tried everything I could with my very limited knowledge of OpenTK and nothing has changed. I have searched on the web and for answer they still have not helped
ANSWER
Answered 2022-Apr-03 at 07:08You actually assign the shader program to a local variable in the event callback function's scope. You need to assign it to the variable in scope of Main
:
ShaderProgram shaderProgram = new ShaderProgram() { id = 0 };
window.Load += () =>
{
Console.WriteLine("Hello");
// ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
};
QUESTION
I'm currently attempting to create a first-person space flight camera.
First, allow me to define what I mean by that.
Notice that I am currently using Row-Major matrices in my math library (meaning, the basis vectors in my 4x4 matrices are laid out in rows, and the affine translation part is in the fourth row). Hopefully this helps clarify the order in which I multiply my matrices.
What I have so Far
So far, I have successfully implemented a simple first-person camera view. The code for this is as follows:
fn fps_camera(&mut self) -> beagle_math::Mat4 {
let pitch_matrix = beagle_math::Mat4::rotate_x(self.pitch_in_radians);
let yaw_matrix = beagle_math::Mat4::rotate_y(self.yaw_in_radians);
let view_matrix = yaw_matrix.get_transposed().mul(&pitch_matrix.get_transposed());
let translate_matrix = beagle_math::Mat4::translate(&self.position.mul(-1.0));
translate_matrix.mul(&view_matrix)
}
This works as expected. I am able to walk around and look around with the mouse.
What I am Attempting to do
However, an obvious limitation of this implementation is that since pitch and yaw is always defined relative to a global "up" direction, the moment I pitch more than 90 degrees, getting the world to essentially being upside-down, my yaw movement is inverted.
What I would like to attempt to implement is what could be seen more as a first-person "space flight" camera. That is, no matter what your current orientation is, pitching up and down with the mouse will always translate into up and down in the game, relative to your current orientation. And yawing left and right with your mouse will always translate into a left and right direction, relative to your current orientation.
Unfortunately, this problem has got me stuck for days now. Bear with me, as I am new to the field of linear algebra and matrix transformations. So I must be misunderstanding or overlooking something fundamental. What I've implemented so far might thus look... stupid and naive :) Probably because it is.
What I've Tried so far
The way that I always end up coming back to thinking about this problem is to basically redefine the world's orientation every frame. That is, in a frame, you translate, pitch, and yaw the world coordinate space using your view matrix. You then somehow redefine this orientation as being the new default or zero-rotation. By doing this, you can then, in your next frame apply new pitch and yaw rotations based on this new default orientation, which (by my thinking, anyways), would mean that mouse movement will always translate directly to up, down, left, and right, no matter how you are oriented, because you are basically always redefining the world coordinate space in terms relative to what your previous orientation was, as opposed to the simple first-person camera, which always starts from the same initial coordinate space.
The latest code I have which attempts to implement my idea is as follows:
fn space_camera(&mut self) -> beagle_math::Mat4 {
let previous_pitch_matrix = beagle_math::Mat4::rotate_x(self.previous_pitch);
let previous_yaw_matrix = beagle_math::Mat4::rotate_y(self.previous_yaw);
let previous_view_matrix = previous_yaw_matrix.get_transposed().mul(&previous_pitch_matrix.get_transposed());
let pitch_matrix = beagle_math::Mat4::rotate_x(self.pitch_in_radians);
let yaw_matrix = beagle_math::Mat4::rotate_y(self.yaw_in_radians);
let view_matrix = yaw_matrix.get_transposed().mul(&pitch_matrix.get_transposed());
let translate_matrix = beagle_math::Mat4::translate(&self.position.mul(-1.0));
// SAVES
self.previous_pitch += self.pitch_in_radians;
self.previous_yaw += self.yaw_in_radians;
// RESETS
self.pitch_in_radians = 0.0;
self.yaw_in_radians = 0.0;
translate_matrix.mul(&(previous_view_matrix.mul(&view_matrix)))
}
This, however, does nothing to solve the issue. It actually gives the exact same result and problem as the fps camera.
My thinking behind this code is basically: Always keep track of an accumulated pitch and yaw (in the code that is the previous_pitch and previous_yaw) based on deltas each frame. The deltas are pitch_in_radians and pitch_in_yaw, as they are always reset each frame.
I then start off by constructing a view matrix that would represent how the world was orientated previously, that is the previous_view_matrix. I then construct a new view matrix based on the deltas of this frame, that is the view_matrix.
I then attempt to do a view matrix that does this:
- Translate the world in the opposite direction of what represents the camera's current position. Nothing is different here from the FPS camera.
- Orient that world according to what my orientation has been so far (using the previous_view_matrix. What I would want this to represent is the default starting point for the deltas of my current frame's movement.
- Apply the deltas of the current frame using the current view matrix, represented by view_matrix
My hope was that in step 3, the previous orientation would be seen as a starting point for a new rotation. That if the world was upside-down in the previous orientation, the view_matrix would apply a yaw in terms of the camera's "up", which would then avoid the problem of inverted controls.
I must surely be either attacking the problem from the wrong angle, or misunderstanding essential parts of matrix multiplication with rotations.
Can anyone help pin-point where I'm going wrong?
[EDIT] - Rolling even when you only pitch and yaw the camera
For anyone just stumbling upon this, I fixed it by a combination of the marked answer and Locke's answer (ultimately, in the example given in my question, I also messed up the matrix multiplication order).
Additionally, when you get your camera right, you may stumble upon the odd side-effect that holding the camera stationary, and just pitching and yawing it about (such as moving your mouse around in a circle), will result in your world slowly rolling as well.
This is not a mistake, this is how rotations work in 3D. Kevin added a comment in his answer that explains it, and additionally, I also found this GameDev Stack Exchange answer explaining it in further detail.
ANSWER
Answered 2022-Mar-02 at 23:15The problem is that two numbers, pitch and yaw, provide insufficient degrees of freedom to represent consistent free rotation behavior in space without any “horizon”. Two numbers can represent a look-direction vector but they cannot represent the third component of camera orientation, called roll (rotation about the “depth” axis of the screen). As a consequence, no matter how you implement the controls, you will find that in some orientations the camera rolls strangely, because the effect of trying to do the math with this information is that every frame the roll is picked/reconstructed based on the pitch and yaw.
The minimal solution to this is to add a roll component to your camera state. However, this approach (“Euler angles”) is both tricky to compute with and has numerical stability issues (“gimbal lock”).
Instead, you should represent your camera/player orientation as a quaternion, a mathematical structure that is good for representing arbitrary rotations. Quaternions are used somewhat like rotation matrices, but have fewer components; you'll multiply quaternions by quaternions to apply player input, and convert quaternions to matrices to render with.
It is very common for general purpose game engines to use quaternions for describing objects' rotations. I haven't personally written quaternion camera code (yet!) but I'm sure the internet contains many examples and longer explanations you can work from.
QUESTION
I'm new to Godot coming fresh from unity and I cant figure out how to duplicate an object/node. I've tried the duplicate function to no effect. My most recent attempts try to create child nodes with the same property as the parent. I cant seem to get anywhere, help would be appreciated. Here is my code that tries to create a child node:
Node copynode = new Node();
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
copynode = this;
for (int i = 0; i < 5; i++)
{
AddChild(copynode);
}
}
Also could someone tell me what the object/node/item in the scene is actually called and how to reference it? Is it a Node or a Gamedot.Object or something else? And how do I get and set its properties? I'm just really used to unity and cant figure this stuff out. The only tutorials I find are in the Godot language, and I kind of know c# already so I would prefer to program in that.
ANSWER
Answered 2022-Feb-19 at 01:11- The base node class is invisible (gray) so you cannot see if they were added or not. You can switch from the local to the remote tab in the scene tree while running to see only one invisible node added.
- If you change the code to
AddChild(copynode).Duplicate();
you can see it adds all 5 invisible nodes.
QUESTION
When I say "Entity" below, I'm not specifically referring to anything relating to the ECS pattern, I just mean a general game entity.
I'm trying my hand at game development in C, after having done previous game dev in TypeScript. I'm looking for a C idiomatic way to reuse a pattern with which I'm familiar: each tick, the game iterates through a list of entities, telling each one to update itself, then draw itself. Each entity knows how to update itself, but requires information about the game as a whole to make this update.
// Game.ts
import Entity from './Entity.js'
class Game {
entities: List;
tick(dt: number) {
entities.forEach(e => e.tick(dt));
entities.forEach(e => e.draw());
}
}
// Entity.ts
import Game from './Game.ts'
class Entity {
game: Game;
constructor(g: Game) {
this.game = g;
}
tick(dt: number) {
this.move(dt);
this.collide(this.game);
}
draw() { /* snip */}
}
In C, I would like to have a big Game struct that has a list of all Entities inside it, and each Entity contains a function pointer for how to update itself.
// game.h
#include "entity.h"
typedef struct Game {
Entity *entities;
} Game;
// entity.h
#include "game.h"
typedef struct Entity Entity;
typedef void (*tick) (Entity*);
struct Entity {
Game *game;
char* name;
int x, y;
tick* t;
};
This, however, requires a circular reference to Game in Entity and Entity in Game, which I've gathered that one is not supposed to do. The only way I've thought of to make this work is to put a tick_entity(Game *game, Entity *e)
function in game.h
, but my OO brain wants to separate my concerns some more to avoid making Game
responsible for everything, especially once I have different kinds of Entities. Is there a more idiomatic way to do what I'm trying to do here?
ANSWER
Answered 2022-Feb-13 at 13:14Don't #include "entity.h"
from game.h
and vice versa. Just forward declare what you need a pointer to. Also add header guards if you haven't already.
Example:
// game.h
#ifndef GAME_H // header guard
#define GAME_H
//#include "entity.h" // remove this
typedef struct Entity Entity; // forward declare
typedef struct Game {
Entity* entities;
} Game;
#endif
// entity.h
#ifndef ENTITY_H // header guard
#define ENTITY_H
//#include "game.h" // remove this
typedef struct Game Game; // forward declare
typedef struct Entity Entity;
typedef void (*tick)(Entity*);
struct Entity {
Game* game;
char* name;
int x, y;
tick* t;
};
#endif
QUESTION
helloI'm making an object in Unity that gives players random weapons when they hover over it, but it always gives me this warning and doesn't create it.
[ClientRpc]
public void spawnTime()
{
StartCoroutine(spawn());
}
public IEnumerator spawn()
{
Debug.Log("oldu");
yield return new WaitForSeconds(1);
int a = Random.Range(0, guns.Length);
GameObject gun =Instantiate(guns[a], spawnPoint.position,Quaternion.identity);
gun.transform.SetParent(transform);
NetworkServer.Spawn(gun);
}
ANSWER
Answered 2022-Feb-10 at 07:54This is because of you are calling the spawn function from client. You should call it in server.
[Server]
public void spawnTime()
{
StartCoroutine(spawn());
}
[Server]
public IEnumerator spawn()
{
Debug.Log("oldu");
yield return new WaitForSeconds(1);
int a = Random.Range(0, guns.Length);
GameObject gun =Instantiate(guns[a],
spawnPoint.position,Quaternion.identity);
gun.transform.SetParent(transform);
NetworkServer.Spawn(gun);
uint gunNetId = gun.GetComponent().netId;
uint parentNetId = transform.root.GetComponent().netId;
RpcSetParent(parentNetId, gunNetId);
}
[ClientRpc]
void RpcSetParent(uint parentNetId, uint childNetId)
{
Transform child = NetworkClient.spawned[childNetId].transform;
Transform parent = NetworkClient.spawned[parentNetId].transform;
child.SetParent(parent);
}
Be sure that you are calling the spawnTime() function from something running in server and networked object. You can filter it something like:
Start(){
NetworkIdentity nid = transform.root.GetComponent();
if(nid.isServer)
{
spawnTime();
}
}
QUESTION
I am trying to learn Godot by making a simple 2D shooter, but am running into a problem. I do not know how to detect if an enemy has been shot by a bullet. My bullets are Area2D nodes with a Sprite, and CollisionShape2D node attached. My enemies are KinematicBody2D nodes with a Sprite, and CollisionShape2D node attached. The enemy also has a timer attached, but that is not important.
Here is the enemy code:
extends KinematicBody2D
var speed = 200
var velocity = Vector2(-0.5, 1)
var bullet_preload = preload("res://Enemy/EnemyBullet.tscn")
func _ready():
randomize()
velocity.y = [1, -1][randi() % 2]
func _physics_process(delta):
var collision = move_and_collide(velocity * speed * delta)
if collision:
velocity = velocity.bounce(collision.normal)
if position.x < -20:
print("Enemy Despawned")
queue_free()
if $ShootDelay.time_left == 0:
var bullet = bullet_preload.instance()
bullet.position.x = position.x - 18
bullet.position.y = position.y + 6
get_parent().add_child(bullet)
$ShootDelay.start()
Here is my player bullet code:
extends Area2D
var speed = 600
var velocity = Vector2(1, 0)
func _process(delta):
position.x += speed * delta
if position.x > 1044:
queue_free()
func _on_PlayerBullet_body_entered(body):
queue_free()
It may be important to note that the player bullet and enemy scenes are not in the same scene tree, and there is no way (that I know of) of sending a signal between them. They are both being instanced to my main root node that contains the entire game via code.
If I need to include other details, please let me know.
ANSWER
Answered 2022-Feb-06 at 03:20On your _on_PlayerBullet_body_entered
you a body
that has a reference to whatever the Area2D
collided with, you can use it to communicate with it.
For example, you can call a method on it. Which could, of course could be queue_free
:
func _on_PlayerBullet_body_entered(body):
body.queue_free()
queue_free()
However, I'm going to suggest against it. Instead let us come up with a method that you can implement to have whatever behavior you want:
func _on_PlayerBullet_body_entered(body):
body.shot()
queue_free()
Of course, we have the problem that we are not sure if it has that method… So, let us check for it:
func _on_PlayerBullet_body_entered(body):
if body.has_method(shot):
body.shot()
queue_free()
Then you would add that method on the objects that react to the bullet impact. Back to queue_free
, it could be:
func shot() -> void:
queue_free()
Or you could have it be something like this:
var health := 5
func shot() -> void:
health -= 1
if health <= 0:
queue_free()
Or, you could have it set a flag and deal with it on _physics_process
or where and whenever appropiate:
var was_shot := 5
func _physics_process(_delta) -> void:
if was_shot:
queue_free()
func shot() -> void:
was_shot = true
Of course, aside form queue_free
you may want to instance some other scene (e.g. a corpse or an explosion) or play an animation or something like that.
QUESTION
I used to handle a group of sprites by push them into an array or sprite group which is build-in class in the Phaser. But I am seeking another simple way could get or remove all sprites in an scene. Does anyone have any idea to resolve this? Thanks a lot!
ANSWER
Answered 2022-Jan-29 at 09:00The Scene has a property children
(link to documentation)
You can get all Sprites, with the command:
// where this = the current scene
let allSprites = this.children.list.filter(x => x instanceof Phaser.GameObjects.Sprite);
And then remove/destroy them all, like this:
allSprites.forEach(x => x.destroy());
Just iterating through the list of sprites, and calling the destroy
function on each object.
QUESTION
I'm trying to create a scoreboard using phaser3. It creates the board when I do the following in create function:
this.gr = this.add.graphics();
this.gr.fillStyle(0xffffff, 0.3);
this.gr.fillRoundedRect(32, 32, 100, 300, 32);
this.gr.fillStyle(0xff00ff, 1);
But it creates it in the top left of the game world and not the screen itself (I'm having to travel to top left of the map to see it rather it being top left relative to window). For context, this is alike agar.io where the player moves around the map with the camera clipped to them.
I tried updating the position using the character sprite's position, but it doesn't flex like it should, and there's probably a more proper way of doing it.
Question: how can I have it be visible relative to the window and not game world?
ANSWER
Answered 2022-Jan-21 at 00:26YourGraphic.setScrollFactor(0,0);
QUESTION
I Am New To Ursana Engine And I Don't Know It Properly. But I Can Make Games In It. But The Problem Is That My Game Doesn't Have Any . So My Game Looks Dead.
Is There Any Way To Make My Game Look Good Using In Ursana Engine?
ANSWER
Answered 2021-Dec-11 at 20:32You have to add lights and also apply lit_with_shadows_shader
to entities that will receive shadow.
See more here: https://www.ursinaengine.org/cheat_sheet.html#DirectionalLight
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install GLXY
You can use GLXY like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the GLXY component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits
Save this library and start creating your kit
Share this Page