Hey guys so Im making my first app. I know this is a pretty loaded question but Im having a hard time following examples because the script code is different. I am making a 2D platform runner. To start, I created the platforms, environment as well as a majority if not all of the physics. The player at this point is just a circle (just a place holder). The circle can move from left to right and jump. I have now, created an actual player sprite and made animations for walking, jumping and idle. How do I apply the new sprite animations to the current circle placeholder as well as the script? My next step is to go into the animator and start making transitions i guess. Im just not sure how to add the animations to my current script. I knew this was going to be a challenge and if there is any other info you need, please let me know. Thanks so much guys.
This is my "Controls.cs" that is currently attached to my circle player/placeholder. My CheckGround is attached to him. Everything else should be in relation to the platforms he is jumping on and I dont think will change. Again, I have a sprite walking, jumping and idle that I would like to take place of the current circle/placeholder. I need the walking animation to take place when the left and right arrows are pressed, the pump animation to play when the jump button is pressed and idle animation to play when the player is just standing still otherwise. Again, thanks so much guys!
using UnityEngine;
using System.Collections;
public class Controls : MonoBehaviour
{
public Rigidbody2D rb;
public float movespeed;
public float jumpheight;
public bool moveright;
public bool moveleft;
public bool jump;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.RightArrow))
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (Input.GetKey(KeyCode.Space))
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
}
if (jump)
{
if (onGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpheight);
}
jump = false;
}
if (moveright)
{
rb.velocity = new Vector2(movespeed, rb.velocity.y);
}
if (moveleft)
{
rb.velocity = new Vector2(-movespeed, rb.velocity.y);
}
}
}
Read about Animation Controller. After you create it you can grab Animator from your gameObject like transform.GetComponent<Animator>()
Later you can blend your animations or just play them. Unity give you even possibility to make input conditions to play your animations so to be honest you don't even have to type too much code.
Definitely use an Animation Controller.
Have a look at this video - I'm following this tutorial at the moment.
https://www.youtube.com/watch?v=I0IVZhHNarg
Related
I implemented input for my mobile game like so:
I have some buttons and I have anywhere else on the screen.
Basically when the player touches the screen and not a button ingame, the character jumps. Now, It is implemented by using OnPointerDown and OnPointerUp that sets a bool:
public class JumpInput : MonoBehaviour
{
public static bool JUMP;
public void PointerDown()
{
JUMP = true;
}
public void PointerUp()
{
JUMP = false;
}
}
If the player is jumping, it is checked by a FixedUpdate method:
if (!movementDisabled && grounded && JumpInput.JUMP)
{
//then we can jump
currentImageIndex = 0;
animState = CharAnimStates.jumpStart;
//added again from here
//zeroing out the Y axis velocity if we had one
rb2d.velocity = new Vector2(rb2d.velocity.x, 0.0f);
//until here
jump = true;
}
As I get decent frame rates even when using post-processing, I have no clue why the input is so delayed. I require assistance to verify if my solution for "anywhere on the screen input" is viable performancewise and it not, how to improve it.
I am making a game in which my player is a UFO, and when the player collides with other game objects, I need the game objects to be attached or floated in the air below the player (UFO), like original UFO. I tried to attach them as a child, but it didn't worked.
I made one script as below:
if (coll) {
distance = Vector2.Distance (this.transform.position, player.transform.position);
if (distance < 2) {
this.transform.parent = encaixe.transform;
this.transform.localPosition = new Vector2 (0f, 1.2f);
this.transform.localRotation = Quaternion.identity;
encaixe.rigidbody2D.gravityScale=0;
}
}
In using this script, the gameobject is attaching, but the player is not moving as like original. The game object is pulling down or up forcefully.
Please suggest to me how to do this.
I know that this Thread is rather old, but maybe someone might come across this question and is in need of an answer.
You can actively set the Object's Position and Rotation to the UFO's on Collision.
Something like the following (pseudocode):
private bool hasCollided = false;
void OnCollisionEnter()
{
hasCollided = true;
}
void LateUpdate()
{
if (hasCollided)
{
followPlayer();
}
}
void followPlayer()
{
//update position and rotation
}
I am a beginner and I want a complete example in LibGDX how to limit the framerate to 50 or 60. Also how to mangae interpolation between game state with simple example code
e.g. deWiTTERS Game Loop:
#Override
public void render()
{
float deltaTime = Gdx.graphics.getDeltaTime();
Update(deltaTime);
Render(deltaTime);
}
There is a Gdx.graphics.setVsync() method (generic = backend-independant), but it is not present in 0.9.1, only in the Nightlies.
"Relying on vsync for fixed time steps is a REALLY bad idea. It will break on almost all hardware out there.
See LwjglApplicationConfiguration, there's a flag in there that let s use toggle gpu/software vsynching. Play around with it." (Mario)
NOTE that none of these limit the framerate to a specific value... if you REALLY need to limit the framerate for some reason, you'll have to handle it yourself by returning from render calls if xxx ms haven't passed since the last render call.
As a complete game engine that LibGDX is, it handles things like this itself. You can configure this at the start of your game, at least with the latest nightlies.
public static void main(String[] args) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "Example";
cfg.useGL20 = false;
cfg.width = 800;
cfg.height = 480;
cfg.vSyncEnabled = true;
cfg.foregroundFPS = 60;
new LwjglApplication(new ExampleGame(), cfg);
}
Now your render loop will be limited to 60 calls per second. As to the actual implementation, you should use a Game and Screens. The Screen interface already has a render method which might look like this:
public void render(deltaTime )
{
...
updateAllEntities(deltaTime);
...
renderAllEntities(deltaTime);
...
}
There is only the render method being called by LibGDX, but you can split up your game logic update and the rendering yourself like in the example above.
Please see the below images.
In the first image you can see that there is box collider.
The second image is when I run the code on Android device
Here is the code which is attached to Play Game (its a 3D Text)
using UnityEngine;
using System.Collections;
public class PlayButton : MonoBehaviour {
public string levelToLoad;
public AudioClip soundhover ;
public AudioClip beep;
public bool QuitButton;
public Transform mButton;
BoxCollider boxCollider;
void Start () {
boxCollider = mButton.collider as BoxCollider;
}
void Update () {
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
if (boxCollider.bounds.Contains (touch.position)) {
Application.LoadLevel (levelToLoad);
}
}
}
}
}
I want to see if touch point is inside the collider or not. I want to do this because right now if I click any where on the scene
Application.LoadLevel(levelToLoad); is called.
I want it to be called if I click on PLAY GAME text only. Can any one help me with this piece of code or can give me another solution to my problem??
Recent Code by following Heisenbug's Logic
void Update () {
foreach( Touch touch in Input.touches ) {
if( touch.phase == TouchPhase.Began ) {
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, 10)) {
Application.LoadLevel(levelToLoad);
}
}
}
}
Touch's position is expressed in screen space coordinate system (a Vector2). You need to convert that position in the world space coordinate system before trying to compare it against other 3D locations of objects in the scene.
Unity3D provides facility to do that. Since you are using a BoundingBox surrounding your text, you can do the following:
Create a Ray which origin is in the touch point position and which direction is parallel to the camera forward axis (Camera.ScreenPointToRay).
Check if that ray intersect the BoundingBox of your GameObject (Physic.RayCast).
the code may look something like that:
Ray ray = camera.ScreenPointToRay(new Vector3(touch.position.x, touch.position.y, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerOfYourGameObject))
{
//enter here if the object has been hit. The first hit object belongin to the layer "layerOfYourGameObject" is returned.
}
It's convenient to add a specific layer to your "Play Game" GameObject, in order to make the ray colliding only with it.
EDIT
Code and explanation above is fine. If you don't get a proper collision maybe you have not used the right layer. I haven't a touch device at the moment. The following code will work with mouse (without using layers).
using UnityEngine;
using System.Collections;
public class TestRay : MonoBehaviour {
void Update () {
if (Input.GetMouseButton(0))
{
Vector3 pos = Input.mousePosition;
Debug.Log("Mouse pressed " + pos);
Ray ray = Camera.mainCamera.ScreenPointToRay(pos);
if(Physics.Raycast(ray))
{
Debug.Log("Something hit");
}
}
}
}
It's just an example to put you in the right direction. Try to figure out what's going wrong in your case or post an SSCCE.
I'd have already post this question in the Andengine forum but there are already some questions regarding this topic, some have replies but the ones i want to know don't have any replies yet.
I'm trying to simulate a player jump like in Super Mario Bros. First, I used a simple contact listener to have a boolean value false when contact occurs but the contact occurs with walls grounds, everything. So, I'm now trying to attach another small body to the bottom of player as foot sensor using WeldJoint. But I couldn't achieve that. The WeldJoint wouldn't stick at all. I tried to create the WeldJoint on an update thread, nothing. I tried with the setposition method to update the sensor position with the player's, but it just positions the sensor below ground.
Any suggestions would be appreciated. Here is how i tried to create WeldJoint.
Player and sensor
mPlayer = new AnimatedSprite(100, 150, PlayerTextureRegion);
PlayerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld,mPlayer,BodyType.DynamicBody, PLAYER_FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(mPlayer, PlayerBody, true, true));
mScene.getLastChild().attachChild(mPlayer);
final Shape mSensor= new Rectangle(mPlayer.getX()+4,mPlayer.getY()+mPlayer.getHeight(),10,4);
final Body SensorBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld,mSensor,BodyType.DynamicBody, SENSOR_FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(mSensor, SensorBody, true, true));
mScene.getLastChild().attachChild(mSensor);
mScene.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() { }
#Override
public void onUpdate(final float pSecondsElapsed) {
this.createJoint(PlayerBody,SensorBody);
.......
Joint Method
private void createJoint(Body Anchor, Body Sensor){
final WeldJointDef join = new WeldJointDef();
join.initialize(Anchor,Sensor,Anchor.getWorldCenter());
this.mPhysicsWorld.createJoint(join);
}
Ok, instead of WeldJoint I used RevoluteJoint, without the motor configuration and it works fine now. Just initialize two bodies using revoluteJointDef and they are stuck like weldjoint. For time being I'm going with revoluteJoint to make two bodies as one.