Bouncing/reflecting my player off walls - c#

I'm recreating a movement system from dragon quest heroes rocket slime on the DS. In that game, the player can hold down the A button and stretch their slime main character in a direction. Letting go of A while it's stretched would sling them off in that direction.
Here's a gif of what it looks like:
Notice how he bounces off the walls diagonally. My replication currently looks like this (ignore the buggy animations :P)
It looks good! However, if I were to hit a wall diagonally, I would just move backwards in the opposite direction rather than reflecting off it.
Here's the code for how I handle bouncing off walls.
IEnumerator wallBounce(Vector2 hitVelocity)
{
playerAnimator.enabled = true;
yield return new WaitForSeconds(.3f);
playerAnimator.CrossFade("Walking " + curDirection, 0); // place holder animation
pVelocity = Vector2.Scale(-pVelocity,new Vector2(0.25f,0.25f));
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
curState = state.blasting;
transform.position = Vector3.MoveTowards(transform.position, endPos, 5f * Time.deltaTime);
}
I know about the Vector3.Reflect method in Unity but I'm not really sure how to implement it into my current code.

I seem to have done it.
I get the reflection vector like this:
Vector3 reflectedVelocity = Vector3.Reflect(pVelocity*.5f, foundHit.normal);
And then pass it to wallBounce as the hitVelocity.
StartCoroutine(wallBounce(reflectedVelocity));
I then changed this line:
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
into
endPos = transform.position + hitVelocity;

Related

Planet Game Unity2D

Like in previous posts i'm trying to make a game where you land on planets and what not,
for the planet rotation i used a parent "ring" and added a rotating script to it:
void Update()
{
Vector3 rotationfloat = new Vector3(0, 0, 2);
transform.Rotate(rotationfloat * rotateSpeed * Time.deltaTime);
}
Just something like that, rotation is nice and all, but then i have an attractor script that is like a gravitational force,
repel = -1;
if (Vector2.Distance(transform.position, planet.transform.position) <= maxDist && Vector2.Distance(transform.position, planet.transform.position) >= minDist)
{
Vector3 desiredPosition = planet.transform.position;
smoothedPosition = (desiredPosition - transform.position) * -1;
rb.AddForce(smoothedPosition * repel);
smoothedPosition = Vector3.zero;
}
Code like that, but when I try landing my player on the planet it makes the player slide across the planet, I've made it so it has a physics material with high friction, but that doesn't work.
You then land on the bottom of the planet and it pulls you to the planet but bounces you off when you touch it, I've checked the physics material (it has no bounce on it).
Anybody might know what is wrong with it?
If you need any more explanation i will try to give you more

Trying to make the player rotate perpendicular to the model's meshes. Unity

I'm currently working on a school game project where i need to have the player climb walls and pick up stuff. I am currently stuck in figuring out how to make the player rotate perpendicular to where the model's faces are while he/she moves towards a corner of a wall as shown below.
Something like this:
I searched for some methods to achieve this but i haven't found anything concrete so far.
Edit: I tried Reasurria's method and it kinda works.
if (Physics.Raycast (transform.position, -transform.up, out hit) && hit.collider.GetComponent<WallModifier> ()) {
transform.rotation = Quaternion.LookRotation (hit.normal, Vector3.right);
//Physics.gravity = hit.normal * -10.0f;
}
My player does indeed rotate correctly pependicular to the slope/wall but then my camera code completly breaks when trying to actually climb the wall. This shows how it looks like in first person and this shows how it looks like in the scene view.
While very funny, it is not obviously desired to have such effect.
Here is the camera code:
void Update () {
if (Input.GetKeyDown (KeyCode.Escape) || toggle && Input.GetMouseButtonDown (0)) {
toggle = !toggle;
}
if (!toggle && Application.isFocused) {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
var md = new Vector2 (Input.GetAxisRaw ("Mouse X"), Input.GetAxisRaw ("Mouse Y"));
md = Vector2.Scale (md, new Vector2 (sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp (smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp (smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp (mouseLook.y, minClamp, maxClamp);
transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized);
character.transform.localRotation = Quaternion.AngleAxis (mouseLook.x, character.transform.up.normalized);
if (rotateModel && antModel)
antModel.transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized) * Quaternion.Euler (0, 90, 0);
} else {
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
Application.runInBackground = false;
}
}
This code was taken by this person.
Do you mean perpendicular? In other words, rotate along x axis with -90 degree.
transform.Rotate(new Vector3(-90, 0, 0));
If I understand correctly, you may want to use Raycast.normal. So you would raycast from your player position with a direction equal to your player's local Vector3.down (player.transform.up * -1.0f).
You can use Quaternion.LookAt(surfaceNormal) to align your players 'up' vector with the normal of the surface under the player. This may involve some 90 degree offset to make the two 'up' vectors match.
Depending on your goal you may also want to set Physics.gravity to surfaceNormal * -10.0f or implement some custom gravity solution if the new surface will function as ground.
You can add empty GameObject with attached collider, than you can use OnTriggerEnter to rotate your Player. Add flag and on every odd enter rotate in one side and on every even enter rotate to opposite side as shingo said
Example

Player rotation and camera rotation

i want the player to look into the direction, the camera is looking.
The camera follows the player (3rd person game style).
I've tried it with
transform.localRotation = new Quaternion(transform.localRotation.x,
cameraMain.transform.localRotation.y,
transform.localRotation.z,
transform.localRotation.w);
but it doesn't work.
Sometimes the player starts rotating the other direction.
the following code will make the object (specified in the parameter) face in the direction of where the main camera is looking:
public void lookInDirectionOfCamera(Transform object) {
RayCastHit hit;
if (Physics.raycast(cameraMain.transform.position, cameraMain.transform.forward, out hit)) {
object.forward = hit.point - object.position;
}else { //if the raycast didnt hit anything, make the object face 100 units in front of the camera
Vector3 point = Camera.main.transform.position + Camera.main.transform.forward * 100;
object.forward = point - object.position;
}
}
This will make the player face the point that is forward to the camera. If you just want them to have the same rotation in the y-axis don't use Quaternions!
Instead, you can just do it with Euler angles:
transform.eulerAngles = new Vector3(transform.eulerAngles.x,
cameraMain.transform.eulerAngles.y,
transform.eulerAngles.y);
The reason not to use transform.localRotation is because that is a Quaternion. The y component in a Quaternion is not the same as the y-axis in a Euler angle (what you are used to seeing), Quaternions are very confusing so you should almost never set individual values in them. If you want to edit them only use the built-in methods.
Get the direction the camera is looking with cameraMain.transform.forward, make a copy with a y value of zero, then use Quaternion.SetLookRotation to look in that direction with the global up direction.:
Vector3 cameraDirection = cameraMain.transform.forward;
Vector3 characterLookDirection = new Vector3(cameraDirection.x,
0f,
cameraDirection.z);
Quaternion newRotation = new Quaternion();
newRotation.SetLookRotation(characterLookDirection, Vector3.up);
transform.rotation = newRotation;

Reflection of velocity no longer works after converting to 3D

I've been making a game based on Dragon Quest Heroes Rocket Slime's tank battle system for a while. First thing I need to get down is it's movement system where the player can stretch and sling themselves in a direction. When they hit a wall they should reflect off it realistically (eg: hitting it diagonally will reflect them diagonally)
My game was in 2D for the most part but figuring out pseudo-3d collision in a 2D space among other issues made it nearly impossible to continue so I moved it to fully 3d.
Everything worked well until I tried bouncing off a wall. If my player hits a wall going up, he goes down and vice versa. However, if my player hits a wall going left it tries to 'reflect' him left when it should reflect him right (and vice versa for hitting it while going right).
The way 'velocity' works in my game is that when stretching a Vector2 called pVelocity goes up based on how much they stretched. When they let go a 'endPos' is created based on currentPosition + pVelocity. The player will then move via Vector3.MoveTowards to that endPos at a constant speed. When hitting a wall I do this:
if (hit && foundHit.transform!=transform && curState != state.wallHit && foundHit.transform.tag!="Object")
{
//we've hit a wall while blasting
//now we make the player 'squish' up against the wall and bounce off!
Vector3 reflectedVelocity = Vector3.Reflect(new Vector3(pVelocity.x,0,pVelocity.y), foundHit.normal);
//playerAnimator.SetFloat("VelocityX", reflectedVelocity.x);
//playerAnimator.SetFloat("VelocityY", reflectedVelocity.y);
curState = state.wallHit;
playerSound.Play();
transform.position = foundHit.point;
playerAnimator.Play("Squish");
StartCoroutine(wallBounce(reflectedVelocity));
}
And in wallBounce, I do this:
IEnumerator wallBounce(Vector3 hitVelocity)
{
playerAnimator.enabled = true;
yield return new WaitForSeconds(.5f);
playerAnimator.Play("Walk blend tree");
pVelocity = new Vector2(hitVelocity.x,hitVelocity.z);
endPos = transform.position + (-transform.forward * pVelocity.magnitude);
curState = state.blasting;
Vector3 diff = endPos - transform.position;
diff.Normalize();
float rot_z = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, rot_z - 90, 0f);
}
When slinging, the player is always facing in the direction they're going so I assume that the issue is somewhere inside wallBounce when I create the new endPos but I'm not really sure how to fix it.
Seems the issue was that my player wasn't looking in the direction of movement when hitting left or right. Adding this in the part before I call MoveTowards worked.
transform.LookAt(endPos);

Unity3D Vector 3 Teleporting

image
Hey Folks!
I attached an image to visualize my explanation of the problem i have. In my game, there is a green ball rolling along an endless road, getting chased by a yellow ball.
To make the road seem endless, the ball gets teleported back (purple line on the bottom image), when it crosses a certain distance on the x-axis (purple line on the top image). I did it like this:
if (gameObject.transform.position.x <= -20) {
gameObject.transform.position = new Vector3 (transform.position.x + 80, transform.position.y, transform.position.z);
}
and it works totally fine.
When the green ball is getting „teleported“, the yellow ball should get teleported back with the same value, so the distance between the too balls doesn’t change after teleporting. So I made a public game object „enemy“, placed the yellow ball inside the enemy field in the inspector and changed the code to this:
if (gameObject.transform.position.x <= -20) {
gameObject.transform.position = new Vector3 (transform.position.x + 80, transform.position.y, transform.position.z);
enemy.transform.position = new Vector3 (transform.position.x + 80, transform.position.y, transform.position.z);
}
But as you can see on the bottom image, the yellow ball wasn’t teleported on the same distance. It seems like the distance is added from it’s original starting point and not from the point it had before teleporting. Hope you guys know a solution for this.
The Yellow Ball has a script to follow the Player, maybe it has to do something with this?
void Update ()
{
//enemy follows the ball with speed 8
transform.LookAt (target);
transform.Translate (Vector3.forward * 8 * Time.deltaTime);
//fix y-position
Vector3 tmp = transform.position;
tmp.y = lockedY;
transform.position = tmp;
}
You want to move the enemy back 80 units, then you need to move the enemy back 80 units.
enemy.transform.position = new Vector3(enemy.position.x + 80,enemy .position.y,enemy.position.z);

Categories