Sonic the Hedgehog-like diagonal bouncer in Unity - c#

I'm working on a 2D platformer game in Unity and i want have a Sonic the Hedgehog like spring, in which when you step on it, player will be bounced very high. What i have come up with so far is this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bouncing : MonoBehaviour
{
public Vector2 bouncingPower;
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Player"))
{
other.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2 (bouncingPower.x, bouncingPower.y);
}
}
This works, but only for y-axis. I set up the force on for y and when the player is stepping on the bouncer it will be bounced high, depending on y value.
However, i also want to have bouncer be at diagonal position, so when the player collides with this kind of bouncer, the player gets thrown diagonally, but when i set up the x value aswell, it sort of works. Player only gets tilted a bit to the side and that's about it. I understand that setting these values only determines how strong would i like player to be bounced as opposed to setting the angle being thrown at.
What would be a good solution have player be thrown in, let's say, 45 degree? I would like it if the player can be bounced at x-axis only aswell, but not really a mandatory.

I know that this is not the best solution, indeed I would have done initially the same, put rigidbody velocity with X-Y vector.
But if you say that this do not works, you can try adding an effector to the "jumper".
Here is a good tutorial of how 2d effector's works.
https://www.youtube.com/watch?v=hgUqhsAzGWs

Related

CharacterController & Collisions issue?

In Runner Game I need to detected collions with Objects. I use CharacterController and OnControllerColliderHit(ControllerColliderHit hit):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mainPlayerScript : MonoBehaviour
{
void OnControllerColliderHit(ControllerColliderHit hit)
{
print(hit.gameObject.name);
}
}
But, if my character collide with some object in front of it - no collision detected! What'd the problem?
P.s. In the game I use the method: my Character always stay. All world moves around it. Is it the best way?
This is because you moved transform.position. use CharacterController.Move() instead.
Controller.Move(SomeMotion * Time.deltaTime);
The onControllerColliderHit only gets called if the controller collides with something while moving using the Charactercontroller.Move() function. Since your character never moves this won't be called.
If you still want the world to move you could try and use a raycast with set max distance to check if something is in front of your player.

Lag occurs after loading from other scenes

Assumptions / What I want to achieve
I am making an action game that moves only the x and z axes in 3D.
I'm trying to make this compatible with online multiplayer.The Player object has such a component.
Use Joystick of StandardAssets for OnlinePlayerController.cs,
There is code to move using the rigidbody velocity.
The code is written below.
The problem I am having
Lag always occurs when loading an online scene from another scene.
Applicable source code
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityStandardAssets.CrossPlatformInput;
public class OnlinePlayerController : MonoBehaviourPunCallbacks
{
public float speed;
[SerializeField]
GameObject Rotation; //Omitted because it has nothing to do with movement
void Update()
{
x = CrossPlatformInputManager.GetAxisRaw("Horizontal");
z = CrossPlatformInputManager.GetAxisRaw("Vertical");
rigd.velocity = new Vector3(x * speed, 0, z * speed);
}
}
What I tried
As you can see from this article, I tried to fix the lag, but there was no change.
The Player object has a Rigidbody only to use Rigidbody.velocity.
Gravity is ineffective and friction with the floor is high and will not slip.
Supplementary information
Unity2019.2.6f1
PUN2 Free
It's important to note that there is no lag when playing from the scene in the editor.
I think that Photon is not the cause, as in other questions, but I think Unity is the major cause. (For example, the previous scene is interfering, etc.)
This is my first time using PUN2, so I don't know much about this.
What should I do to solve this?
Sorry, everything was my mistake.
This code was running before the scene transition.
Time.fixedDeltaTime = 0.2f;

My projectiles wont collide with my enemies in a 2D side scrolling Unity project?

As the title suggests, I've literally just started learning Unity recently and I'm practising by making a side scrolling shooter. I've been following a Udemy course about it and (to my knowledge) I've been following the tutor's instructions to the letter, but at the point where he tests his and it works fine, by projectiles go straight through my enemies.
I'm a bit stumped at this point and so I thought I'd post here to see what you guys thought. I bet it's something really simple I've not done.
Please see my projectile code below:
using UnityEngine; using System.Collections;
public class DestroyEnemyAndProjectile : MonoBehaviour {
public GameObject WhiteExplosion;
public GameObject OrangeExplosion;
void Start()
{
}
void Update()
{
}
void OnCollisionEnter2D (Collision2D tempCollision)
{
if (tempCollision.gameObject.tag == "Collision")
{
spawnParticles(tempCollision.transform.position);
Destroy(tempCollision.gameObject);
}
}
void spawnParticles(Vector2 tempPosition)
{
Instantiate(WhiteExplosion, tempPosition, Quaternion.identity);
Instantiate(OrangeExplosion, tempPosition, Quaternion.identity);
}
}
Thanks for your help!
I did post a question to them which got a response, they suggested that perhaps the projectile is going too fast and check there was a Rigidbody 2D attached - both of which were already collect
make sure that the object you're colliding with has the tag "Collision", with the same capitalisation.
If it's not, you can do this by:
1. Selecting the GameObject to be collided with
2. In the top-right, select the Tag property
3. Add tag, click the plus and type in "Collision"
4. Select the GameObject again, and select the "Collision" tag from the Tag property dropdown
Otherwise, if that's not the issue. Make sure the projectile has a type of Collider2D component, and that the projectile, or the object being collided with, has a Rigidbody2D.
First I would like to know what the behaviour of this script curently is. Is the collision method being called, and the projectile goes through the enemy anyway? Or the collision method is not being called at all?
That being said, these are things that you should check in order for collision to work:
Make sure that the projectile and the enemy have Collider2D components attached to them.
Make sure that the projectile and/or the enemy (at least one of them must) have a Rigidbody2D attached to it.
Make sure that the layer of the projectiles and the layer of the enemies are set to collide in the collision matrix (You can find the collision matrix in Edit->ProjectSettings->Physics)
Make sure that the enemy GameObject has its tag set to "Collision".
P.S: Welcome to Unity where issues like this are, in fact, usually caused by something super simple that you probably missed.

Find and add the velocity of a Rigidbody that's directly below another? (Unity + C#)

I have an issue that I've not been able to solve for a few days now and without it working I can't move on with my project, so your help would be greatly appreciated!
What I'm trying to do is 'find' the velocity of an object that is directly below my 2D sprite (that also contains a Rigidbody and 2D box collider) and then add that velocity (in the same direction) to the object that is 'looking' for it.
I feel like ray-casting might be part of the answer but I'm not sure how to use that, especially in this context.
The idea behind this is I have a platform that can carry objects stacked on top of each other, so you move the mouse, it manipulates the platforms velocity, but this causes the objects on-top to fly backwards, no mater how high the friction is.
Here is the platform code:
void Update()
{
float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen));
mouseDelta = pos_move - lastMousePosition;
acceleration = mouseDelta.x * 0.4f;
platformVelocity += acceleration;
platform.velocity = new Vector2(platformVelocity, 0) * speed;
lastMousePosition = pos_move;
}
Thank you for taking the time to read this, I would very much appreciate any help you can give!
Is it necessary to 'find' that object? 'Finding' may be difficult & costing.
Can you hold the 'below-thing' reference and pass it to 'above-thing'?
I'm assuming you have some method on objects that checks whether it's on a moving platform. One option is to add an IsOnMovingPlatform flag on those objects. Then use a similar method to check if any object is on top of the "IsOnMovingPlatform == true" objects. Keep doing passes on that method until you don't come up with any more flags set to true.
So, i'm trying to understand your question and I think I might know what you're talking about.
Are you saying that you want your game object (2d sprite) to stay on the platform as its moving? I have had the same problem, where a platform is moving and my player (game object) slides off- and this is how I fixed it.
Add a box collider to the platform (trigger). When the player enters the platform, make the player's transform the platform. That way, when the platform moves- the player moves with it no matter what the speed is.
For example:
void OnTriggerEnter2D(Collider2d collider){
if(collider.tag.equals("Player")){ // you only want the player to work
// attach script to platform for "this.transform" to work
collider.transform.SetParent(this.transform);
}
}
then, to unparent the transform "otherwise, even when the player is off the platform, it will move with the platform.
void OnTriggerExit(Collider2d collider){
// assuming your player isn't supposed to have a parent!
collider.transform.parent = null;
}
Sorry if I misunderstood your question! If this is what you were going for, finding the velocity of the platform is not necessary. Also, this is uncompiled code- if you have issues let me know.
EDIT:
To add a bit of a give, for the entire duration that the player is in contact with the platform, we can add a little bit of a negative force to shove the player a little bit!
We do this by using OnTriggerStay2D (assuming your game is 2d, otherwise use OnTriggerStay).
For example:
void OnTriggerStay2D(Collider2d collider){
if(collider.tag.equals("Player")){
collider.getComponent<Rigidbody2D>().addForce(new vector2(forceToAdd, 0));
}
}
now, that "forceToAdd" variable should be based on the speed and direction that your platform is going. Does your platform have a rigid body on it? if so you can get your force variable by retrieving the rigid body from the platform (getcomponent()) and get the X velocity from it. With this velocity, experiment with dividing it by numbers until you find a good fit, multiply it by -1 (because you want to push the player in the opposite direction of the platform travel), then this will be your forceToAdd!
However, if your platform is not using a Rigidbody, then a way you can do this is record the x positions in your script (just two positions, and subtract these to find the distance in an update method), multiply by -1, try dividing by a number (experiment with this) and that can be your force to add variable.
Also, my code for the OnTriggerStay2d is rough, the spelling could be a bit wrong- but this will give you a rough idea for a solution! ALSO.. I don't think getting the component of a rigid body should be done in every frame, a way around this would to have your rigid body component as a global variable in the script, then set your rigid body on OnTriggerEnter2d, this way it will only retrieve it once (instead of every frame) which I assume would be more efficient!
Good luck! and if you have any questions il try to help!
This is a raycast2d version, I tested it and it works much better than the trigger collider version :).
using UnityEngine;
using System.Collections;
public class RaycastFeetDeleteLater : MonoBehaviour {
[SerializeField] private float raycastDist = 0.1f;
[SerializeField] Transform feet;
[SerializeField] private float xForceDampener = 0.1f;
private Rigidbody2D rb2d;
// Use this for initialization
void Start () {
rb2d = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void FixedUpdate () {
RaycastDown ();
}
private void RaycastDown(){
RaycastHit2D hit = Physics2D.Raycast (feet.position, Vector2.down, raycastDist);
if (hit.collider != null) {
print (hit.transform.tag);
if (hit.collider.tag.Equals ("Platform")) {
transform.SetParent (hit.transform);
Vector2 force = new Vector2 ((hit.transform.gameObject.GetComponent<Rigidbody2D> ().velocity.x * xForceDampener) * -1, 0);
print (force);
rb2d.AddForce (force);
} else if (transform.parent != null) {
print ("UNPARENT");
transform.parent = null;
}
} else {
if (transform.parent != null) {
transform.parent = null;
}
}
Debug.DrawRay (feet.position, Vector3.down, Color.green, raycastDist);
}
}
This script is attached to the player! No need to have scripts on the platforms, which was the main reason my previous method was a pain :P
Basically this script does the following:
- Gets rigidbody2d of the player on start (we will be adding forces to the player with it soon, so might as well store it in a variable!
On FixedUpdate (Different than Update, FixedUpdate is called on Physics update, where as Update is called every frame) I have read that raycast should use FixedUpdate, I suppose because it is a Physics method!
RaycastDown shoots a 2D raycast directly down from the feet position (to get the feet, create a child object of the player, put the position of the feet a tiny bit below the player, NOT ON THE PLAYER- I will explain why in a second why that will mess up everything! Then drag the feet GameObject on to the "feet" slot of the script.)
Raycast shoots from feet directly down at a distance that is changeable in the editor (raycastDist) I found a distance of 0.1f was perfect for my needs, but play around with it for yours! You can actually see a drawing of your Ray by using Debug.DrawRay as seen in the code, the ray is only visible in the editor- not game view! But this will help, especially with positioning the feet.
Checks if it hit an object with a collider, if so check if the objects tag is a Platform (set the platforms to a new tag and call it Platform).
If it hits a platform set the parent of the player to the platform (like the last script) and start applying a little force to the player in the negative direction that the platform is traveling (we get the rigid body of the platform to find its velocity).
If the raycast does not hit a platform, unparent it so the player can move freely.
Thats basically it, however...
Please note:
This script needs to be on the player, not any of the players child objects, since this script will unparent the player from any platforms- if you have the script on a child object of the player it will unparent from the player- which is horrible. So The script MUST be on the root game object of the player. There are ways around this if for some reason you can't.
As mentioned before, the "feet" child object must be a little bit under the player- this is because when the Raycast2d "fires" it will find the FIRST object with a collider it hits- so if you have the start of the raycast hit a collider on the player then it will always show the raycast hitting the player, not a platform. So to get around this have the raycast fire from the feet- and have the feet position a tiny bit below the player. To help with this I added a print statement that will print to the console which object the raycast is hitting, if it doesn't say "Platform" then you need to lower the feet! :)
Furthermore, I'm not sure how you are moving your platforms- but if the Velocity of the platform always prints "0,0" then its because you are moving the platforms position directly, instead of moving it by forces (this happened to me when I was testing this script). I got around this by moving the platform by "AddForce". Also depending on the "Mass" of your platforms, you may need to drastically increase the "xForceDampener" which I should of actually labeled "xForceMultiplier" as I found while testing I needed to set it much higher- like at 60, instead of 0.25 which I previously thought would be okay..
Hope this helped :D
EDIT: Linking the unity docs for 2D Raycasts in case you need
http://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html

How to find out if something will collide with something in Unity (2D)

I am trying to make a 2D game in Unity and I was curious if there is a way to check if there WILL be a collision between 2 objects rather then telling me WHEN they actually collide.
For Example - I am making a Space Invaders game and I want to check if any one of the space invaders on the edges will collide with a edge before they actually move in a C# script. I coded in Game Maker Studio and I remember that function being available but I am having a hard time finding out if its possible in Unity. Is this possible in Unity?
Thanks for the help.
yes its possible, you would have to do some sort of raycasting in the direction that the gameobject is moving you can check This Link for Physics.Raycast to see how to go about doing what youd like
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void Update() {
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, 10))
print("There is something in front of the object!");
}
}

Categories