C# Creating Authentic Camera /w head - c#

I've been dabbling with this problem for a few days now, which is really embarrassing, cause you'd think it would be really easy to fix.
I'm working on making the Camera function for a game I'm making in XNA (yes, I know XNA is no longer supported, please stop telling me). It is being developed for the Oculus Rift, and I got it partially working, with joints from Shoulders to Neck, and Neck to Head.
The eyes are what is currently troubling me. Currently, when looking straight forward, it works fine. But as soon as I rotate (Pitch), the eyes do not follow. They basically get stuck on the same offset (like, x+2 and x-2 from camera position), which means that when I turn 180 degrees around, the eyes are now swapped. So my left vision is my right camera, and vice versa.
Here's my code:
[CameraController.cs]
public override void Update(GameTime gameTime)
{
Vector3 leftEyePosition = GetEyePosition(Eyes.Left);
Vector3 rightEyePosition = GetEyePosition(Eyes.Right);
_leftEyeCamera.Update(gameTime, leftEyePosition, NeckHead.Yaw, NeckHead.Pitch, NeckHead.Roll, 2);
_rightEyeCamera.Update(gameTime, rightEyePosition, NeckHead.Yaw, NeckHead.Pitch, NeckHead.Roll, -2);
}
private Vector3 GetEyePosition(Eyes eyes)
{
Matrix neckHead = GetHeadPositions();
Vector3 eye = (eyes == Eyes.Left ? neckHead.Left : neckHead.Right);
Vector3 eyePosition = NeckHead.Position;
return (eye + eyePosition);
}
private Matrix GetHeadPositions()
{
Matrix shoulderNeck = ShoulderNeck.GetMatrix();
Matrix neckHead = NeckHead.GetMatrix()*shoulderNeck;
return neckHead;
}
[Joint.cs]
public class Joint
{
private float _pitch;
private Vector3 _position;
private float _roll;
private float _yaw;
public Joint(Joint childJoint, Vector3 position)
{
ChildJoint = childJoint;
Position = position;
}
public Vector3 Position { get; set; }
public float Yaw { get; set; }
public float Pitch { get; set; }
public float Roll { get; set; }
public Joint ChildJoint { get; private set; }
public Matrix GetMatrix()
{
return Matrix.CreateFromYawPitchRoll(Yaw, Pitch, Roll);
}
}
[FpsCamera.cs Update method]
public void Update(GameTime gameTime, Vector3 position, float yaw, float pitch, float roll)
{
Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(pitch, yaw, roll);
Vector3 transformedReference = Vector3.Transform(Vector3.Forward, rotationMatrix);
Vector3 target = transformedReference + position;
view = Matrix.CreateLookAt(position, target, rotationMatrix.Up);
}
As far as I can tell, this should be working, right? I think it might be a problem with one of the matrices, but if I knew, I wouldn't be asking, so... Anyone got a hunch?
Complete classes:
http://pastebin.com/zUVwAPFt
http://pastebin.com/jTbnNsJm
Thanks
Bjarke
Ps. Shorted it down for all you guys asking.

Right. Silly me. After about a week of researching, I finally went to see if what I thought I was completely sure of, wasn't true. I'd mixed up what directions Yaw and Pitch works, which obviously resulted in VERY odd-working code.
So in the end, if anyone has a problem similar to this, if it is not the Yaw, Pitch or Roll axis that's a problem, you wont find the answer here.

Related

OnPhotonSerializeView callback is not working in photon pun2

I'm creating multi-play game using photon pun2.
I'm setted the components inherited from the IPunObservable to object contain a photon view.
but, OnPhotonSerializeView is never called.
This code is a function that synchronizes the position and others. but, it didn't work. and it doesn't catch a break point.
This object is created through PhotonNetwork.Instantiate, and here is the contents of the source and prefab.
using Photon.Pun;
using UnityEngine;
public class Character : MonoBehaviourPun, IPunObservable
{
[Header("Properties")]
public float hp;
public float maxHp;
public bool isMoving;
public float moveSpeed;
public Vector2 moveDirection;
private void OnEnable()
{
PhotonNetwork.AddCallbackTarget(this);
}
private void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
/** skip **/
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
Debug.Log(nameof(OnPhotonSerializeView));
if (stream.IsWriting)
{
stream.SendNext(transform.position);
stream.SendNext(hp);
stream.SendNext(maxHp);
stream.SendNext(moveSpeed);
stream.SendNext(isMoving);
stream.SendNext(moveDirection);
}
else if (stream.IsReading)
{
transform.position = (Vector3)stream.ReceiveNext();
hp = (float)stream.ReceiveNext();
maxHp = (float)stream.ReceiveNext();
moveSpeed = (float)stream.ReceiveNext();
isMoving = (bool)stream.ReceiveNext();
moveDirection = (Vector2)stream.ReceiveNext();
}
}
}
Or is there anything I missed about OnPhotonSerializeView?
I understand that it repeats every second as many frames as specified by PhotonNetwork.SerializationRate or PhotonNetwork.SendRate.
sorry about my poor english...
I want to know about is why not OnPhotonSerializeView called or my wrong knowledge about that.
+added
I'm checked that OnPhotonSerializeView called when player entered two or more. but, not.
I'm used PhotonTransformView. but, it's not synchronized transform too.
PunRPC is working normally.
this is skipped source
private void FixedUpdate()
{
if (photonView.IsMine)
{
MoveEvent();
}
}
protected virtual void MoveEvent()
{
isMoving = moveDirection != Vector2.zero;
if (isMoving)
{
transform.position = transform.position + moveDirection * moveSpeed * Time.deltaTime;
}
}
++added
enter image description here
i founded cloned object on other client view. and it's properties are empty. why is this happening?
there is problem on creating room! i will check my room options or typed lobby. Thank you to everyone try to help me.

How to freez Y rotation in unity transform.LookAt()?

using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
public Transform target;
private void Update()
{
transform.LookAt(target);
}
}
I need to delete Y rotation in LookAt, help me!
(Im add some iformation cose STACKL OVERFLOW want some more information from me)
im guessing what you're implying is zeroing out the y axis.
in that case, after you call your LookAt, you want to reset the y axis
YOURS
private void Update()
{
transform.LookAt(target);
//reset the y axis here.
}
FIXED
private void Update()
{
transform.LookAt(target);
transform.rotation.y = 0;
//make sure to call that after LookAt, otherwise it will override the other line
}
i'd recommend you watch a few tutorials instead of being fed code.

Unity how to "power bounce" one object from another relative to it's angle?

I'm working on a simple 3D game where some balls (fixed Z position) fall along a path (using gravity and physics material) to a small flat platform and "power bounce" off this platform. The player can rotate this platform so I want to recreate a realistic bounce direction according to the platform's angle.
I'm new to coding but so far I've figured the relationship between the vector of the ball as it comes into collision with the platform and the platform's normal, which should be a perpendicular line from the surface and that can be used to reflect the ball's vector to the other direction.
I already used OnCollisionEnter and if statement to detect whether it's the platform you are colliding with, but I don't understand where to indicate the normal of the surface and how to access it. Should it be as a public class in the other object or can it be detected from the ball game object?
I tried some examples from this and other websites and got this far:
public class OnCollision : MonoBehaviour
{
public float speed = 25f;
public Rigidbody rb;
private Rigidbody rigid;
private void Start()
{
rigid = transform.GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "BouncePad") {
rb.velocity = transform.up * speed;
}
}
}
Now it bounces off vertically, so I'm guessing I should change the code where the transform.up * speed part is.
Could anyone guide me, please?
Much appreciated.
If you are already using Physics material, look into the Bounciness property. A value of 0 means no bounce, a value of 1 will lead to no loss of energy. The angle of the bounce will be calculated for you. Make sure you drag the physics material onto each object-- both the ball and the wall's material will have an effect.
Finally somebody gave me a hand and came to this solution:
public class Bounce : MonoBehaviour
{
public Rigidbody rb;
public float str = 0.21f;
public float str2 = 0.15f;
// Start is called before the first frame update
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "BouncePad")
{
rb.AddForce(rb.velocity * str, ForceMode.Impulse);
}
if (col.gameObject.tag == "BouncePad2")
{
rb.AddForce(rb.velocity * str2, ForceMode.Impulse);
}
}
// Update is called once per frame
void Update()
{
}
}
public class BouncTest : MonoBehaviour
{
[SerializeField] private float hight = 3;
[SerializeField] private int times = 5;
[SerializeField] private float speed = 8;
private Vector3 _startPos;
private bool _checkUP;
private int _countTimes;
private float _hightbuf;
[HideInInspector]
public bool _bounceEnd;
private void Awake()
{
_startPos = transform.position;
}
public void TurnOnBounceEffect()
{
_bounceEnd = true;
_checkUP = false;
_hightbuf = hight;
_countTimes = 0;
}
private void FixedUpdate()
{
BounceEffect();
}
private void BounceEffect()
{
if (_bounceEnd)
{
if (!_checkUP)
{
if (transform.position.y <= (_startPos.y + _hightbuf))
transform.position = Vector2.MoveTowards(transform.position, new Vector2(_startPos.x, transform.position.y) + (Vector2.up * _hightbuf), speed * Time.fixedDeltaTime);
else
{
_checkUP = true;
}
}
else if (times != _countTimes)
{
if (transform.position.y > _startPos.y)
transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
else
{
_countTimes++;
_checkUP = false;
_hightbuf /= 2;
}
}
else
{
transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
if (transform.position.y <= _startPos.y)
{
_bounceEnd = false;
}
}
}
}
}

Unity3d: My knockback script is not working

My code doesn't work. When I collide with an object nothings really happening, I made sure that my objects box collider is checked to isTrigger, and I also increase the explosionStrength. What am I doing wrong could anyone help?
public class Knockback : MonoBehaviour
{
public float explosionStrength = 10.0f;
void OnTriggerEnter2D (Collider2D target_)
{
Vector3 forceVec = -target_.GetComponent<Rigidbody2D>().velocity.normalized * explosionStrength;
target_.GetComponent<Rigidbody2D>().AddForce(forceVec,ForceMode2D.Force);
}
}
You are mixing unity3d code and unity 2d code if you are in unity 3d then your code may need to be changed to this...
public class Knockback : MonoBehaviour {
public float explosionStrength = 10.0f;
void OnTriggerEnter (Collider target_){
Vector3 forceVec = -target_.GetComponent<Rigidbody> ().velocity.normalized * explosionStrength;
target_.GetComponent<Rigidbody>().AddForce(forceVec,ForceMode.Force);
}
}
If you are in 2d your code may need to be changed to this
public class Knockback : MonoBehaviour {
public float explosionStrength = 10.0f;
public GameObject player;
void OnTriggerEnter2D (Collider2D target_){
Vector2 forceVec = new Vector2 (-target_.GetComponent<Rigidbody2D> ().velocity.normalized.x * explosionStrength, -target_.GetComponent<Rigidbody2D> ().velocity.normalized.y * explosionStrength);
target_.GetComponent<Rigidbody2D>().AddForce(forceVec,ForceMode2D.Force);
}
}
I have tested the 2d code and it has worked fine. Just make sure you put it on the object to explode not the player.

XNA C# creating an Isometric view with 3D models

I'm trying to make a simple isometric game engine but have some problems with the camera. When i have it like this i can see my model from the front. But i want to see it from an isometric perspective. I tried using a lot of methods but none seem to work. Perhaps I got stuck in the code itself? Can you guys help me with the code perhaps?
public class Camera : PositionedObject
{
#region Fields
private Matrix cameraRotation;
#endregion
#region Properties
public Matrix View
{
get;
set;
}
public Matrix Projection
{
get;
protected set;
}
public Vector3 Target
{
get;
set;
}
#endregion
#region Constructor
public Camera(Game game, Vector3 position, Vector3 target, Vector3 rotation, bool Orthographic, float near, float far)
: base(game)
{
Position = position;
RotationInRadians = rotation;
Target = target;
if (Orthographic)
{
Projection = Matrix.CreateOrthographic(Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height,
near, far);
}
else
{
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width / (float)Game.Window.ClientBounds.Height, near, far);
}
}
#endregion
#region Public Methods
public override void Initialize()
{
base.Initialize();
cameraRotation = Matrix.Identity;
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
cameraRotation = Matrix.CreateFromAxisAngle(cameraRotation.Forward, RotationInRadians.Z)
* Matrix.CreateFromAxisAngle(cameraRotation.Right, RotationInRadians.X)
* Matrix.CreateFromAxisAngle(cameraRotation.Up, RotationInRadians.Y);
Target = Position + cameraRotation.Forward;
View = Matrix.CreateLookAt(Position, Target, cameraRotation.Up);
}
public void Draw(BasicEffect effect)
{
effect.View = View;
effect.Projection = Projection;
}
#endregion
}
The easiest way is to calculate the camera position based on the focus point (a point on your ground, or whatever).
//Lets start with looking at origo for now.
Vector3 FocusPoint = Vector3.Zero;
//This tells us where the camera should be, RELATIVE to the point we are watching.
//I set this a little up and a little back
Vector3 CameraOffset = new Vector3(0f, 20f, 20f);
Matrix ViewMatrix
{
get
{
//The Offset is just up and back, we need to rotate it 45*
var rotatedOffset = Vector3.Transform(CameraOffset, Matrix.CreateRotationY(MathHelper.PiOver2 * 0.5f));
//Now we can create out viewmatrix. No need to use a transformed "up" unless it's not going to be upside down or something.
return Matrix.CreateLookAt(rotatedOffset, FocusPoint, Vector3.Up);
}
}

Categories