How to Draw a Ray Along a Sprite in Unity - c#

I am trying to cast a ray along a sprite in Unity. I have Created an empty GameObject and made it as Parent to different Textures of Head, Hand, Chest etc of a Character to easily Animate it, Now for Melee Combat I would like to Cast a Ray along the Hand Texture while it Animates the Attack but I am Unable to get the Centre of the Hand Texture in the Scene.
I am trying to Access the Sprite by the following Code
Sprite Hand = gameObject.GetComponentsInChildren <Transform> () [4].GetComponentsInChildren <Transform> () [0].gameObject.GetComponent <SpriteRenderer> ().sprite;
This Code is Working for accessing the Hand Transform I verified by Drawing a Ray from the transforms centre

Rather than trying to find it at run time, just link it together in the prefab/gameobject. It's pretty simple to just expose it in the inspector then drag the sprite to the exposed variable. You could do a sprite or a transform, in the example below I used a transform, but if you need to get more data from it then go on ahead and use a sprite.
public Transform Head;
public Transform Hand;
public Transform Chest;
Then you can get the position with Head.position
If you are looking to check for collisions consider placing a collider at each location, then you can toggle them on/off when you want (so the hand collider is disabled unless if the character is punching, then you turn it on for the duration (or part of it) of the punch.) Then you can have a component on just that collider for doing damage or finding a wall or whatever you are trying to accomplish.

Related

How to make a freelook camera to lookat and follow object through what the player is looking at?

it's a bit tricky.
the problem is that the target object is moving and bouncing so if i will make the freelook camera to lookat or follow the moving object the camera will also bounce and i don't want it.
what i want to do is the first part just like it is now the camera is moving behind the player while the player is looking at the moving target. then when the camera is behind the player the moving object is getting out of the screen area. the player head is still looking at it but the camera keep looking and follow the player.
i want somehow to make that the camera will rotate looking at the moving object but from the player point of view and not that the camera will follow/lookat the moving object.
here is a screenshot at the point the moving object(in red circle) is start moving out of the screen :
now i'm not sure how to move to the next part.
at this point i want the camera to stay behind the player and rotate looking at the moving object "like" through the player eyes.
i tested it again now and while the object is moving and the camera is behind the player like in the screenshot i can rotate the camera with the mouse like rotating the camera with the player head looking at the moving object the question how to do it by script ?
i want to rotate the camera with the player head to look at the moving object through the player point of view so the camera will not get the moving object bouncing and other effects.
This screenshot explain what i mean that the camera is still looking at the player and following the player but viewing with the player at the moving object. in this case i'm rotating the freelook camera with my mouse but i want to do it in the script.
well not sure what you are using currently as there is no code provided here ... but instead of directly passing in the target object's position simply use a vector where x and z come from your target object while y comes from your player object like e.g.
// not necessarily the player itself but the usual target object for your camera
Transform player;
Transform camera;
Transform lookTarget;
camera.position = /*Just the usual way how you get your camera position*/;
var targetPosition = lookTarget.position;
targetPosition.y = player.position.y;
// Snapping see https://docs.unity3d.com/ScriptReference/Transform.LookAt.html
camera.LookAt(targetPosition);
// or if you are e.g. using smooth interpolation
var targetRotation = Quaternion.LookRotation(targetPosition - camera.position);
camera.rotation = Quaternion.Slerp(camera.rotation, targetRotation, 5f * Time.deltaTime);

How to drop a box to the mouse position?

I am trying to learn unity, and made my first own game and stucked at the beginning. The first idea was to drop a box (cube) to the mouse position. There are many videos and posts about getting the mouse position, and i tried to use them. My problem is, the mouse position i got is the camera's position, instead of the plane.
As you can see, it is kinda works, but it isn't fall to the plane.
https://prnt.sc/lmrmcl
My code:
void Update()
{
Wall();
}
void Wall()
{
if (Input.GetMouseButtonDown(0))
{
if (Input.GetMouseButtonDown(0))
{
wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
Rigidbody wallsRigidbody = wall.AddComponent<Rigidbody>();
wall.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
wallsRigidbody.mass = 1f;
wallsRigidbody.angularDrag = 0.05f;
wallsRigidbody.useGravity = true;
wallsRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
wall.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
Debug.Log(Camera.main.ScreenToWorldPoint(Input.mousePosition));
BoxCollider wallsCollider = wall.AddComponent<BoxCollider>();
wallsCollider.size = new Vector3(1f, 1f, 1f);
}
}
How should i change my code to get the right position?
This isn't a direct answer to your question, but I'm hoping it'll still get you where you need to go.
Prefabs are your friends! I'd highly recommend leveraging them here instead of constructing a cube directly in code.
But first, make sure everything else is set up right. Go ahead and construct a cube by hand in the Editor and make sure that when you hit Play, it falls as you expect. It should, provided it has a Rigidbody, collider, and you have gravity enabled (true by default).
If that works, drag that cube from your Hierarchy view into a folder in the Project view. This creates a prefab. You can now delete the cube from the Hierarchy view.
Update your script to have a public GameObject field, e.g.
public GameObject cubeToCreate;
Then, in the Inspector pane for whatever gameobject has that script attached, you should get a new field, "Cube To Create". Drag your prefab cube into that slot.
Lastly...update your code to wall = Instantiate(cubeToCreate). You'll still need to update the position, but you should be able to drop the rest of the initialization logic you have above, e.g. setting mass and drag.
As for the actual problem, the first thing that concerns me is how do you plan on turning a 2d mouse click into a 3d point? For the axis going "into" the screen...how should the game determine the value for that?
Camera.main.ScreenToWorldPoint accepts a Vector3, but you're passing it a Vector2 (Input.mousePosition, which gets converted to a z=0 Vector3), so the point is 0 units from the camera -- so in a plane that intersects with the camera.
I haven't done this, but I think you'll need to do raycasting of some sort. Maybe create an invisible 2d plane with a collider on it, and cast a physics ray from the camera, and wherever it hits that plane, that's the point where you want to create your cube. This post has a couple hints, though it's geared toward 2D. That might all be overkill, too -- if you create a new Vector3 and initialize it with your mouse position, you can set the z coordinate to whatever you want, but then your cube creation will be in terms of distance from the camera, which is not the best idea.
Hope this helps.

Unity: Gravity in all directions

I am trying to make a game with magnets. Each magnet has its own magnetic field which pulls the player towards the magnet.
The player should then be able to walk alongside the magnet on its entire side.
The player should not be pulled towards the center.
Right now I have done this by adding velocity to the player towards the magnet, this works fine.
The issue right now is that the player should rotate with his feet towards the magnet. Right now I can't figure out how to change the rotation of the player based on the rotation of the magnet. Which results in the player being on its side or upside down on the magnet in some case.
I am also using a third-person camera from unity standard assets, sometimes when the player is rotated the camera can only look up and down. To fix this I use a rotate function around World.Space.
You should get the position relative, the magnet as parent and your player as child. To do that you could create a different gameObject with the same position as the player, and set it as child to the magnet (or have a child on the magnet which you change its position (absolute position)).
Once you've done that, you normalize the localposition of the magnetChild and you make the player lookAt (there's a function in Unity) this vector + player.position. And you'll have to rotate the player 90ยบ from the x-axis (to make that not the front of the player is looking to it, but the head).
I haven't tried it, but give it a try maybe it works. Something like:
magnetChild.position = player.position;
player.LookAt(player.position + magnetChild.localPosition.normalized);
player.Rotate(90.0f, 0.0f, 0.0f);

How to place objects when clicking onto mesh Unity

So I have this mesh that I generate using perlin noise
What I want to do is to be able to click to place an object in the game. My ultimate goal is to have a menu so you can place different objects but I want to just try to get a cube to work. I tried RayCasting:
public class Raycast : MonoBehaviour
{
Ray myRay; // initializing the ray
RaycastHit hit; // initializing the raycasthit
public GameObject objectToinstantiate;
// Update is called once per frame
void Update()
{
myRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(myRay, out hit))
{
if (Input.GetMouseButtonDown(0))
{
Instantiate(objectToinstantiate, hit.point, Quaternion.identity);
Debug.Log(hit.point);
}
}
I could not get this to work... I had no real idea how to use this script either (like what object to place it on) I tried just making a cube and putting the script on that but It did not work. I got no errors it just did not work.
I also had a mesh collider on my mesh and a box collider on my cube.
I see that you are following the tutorial on YouTube "Procedural Landmass Generation", which I would say is an excellent way to understand the basics of procedural content generation.
For your question I would suggest you add a camera on the top of the terrain, from where you will be able to point with your mouse where you want to instantiate the object (the cube for example). You would need a function which raycasts to the your land tiles. Check if its gameobject's tag is "Terrain" and check if there is no water at that current location. If terrain check returns true and water check returns false, then instantiate your desired object at the "hit" position of the raycast.
You can put the script on any object you want. I'd propose the camera. After adding this script-component to the camera, drag your mesh (that you want to instantiate) into the "objectToinstantiate" slot you see in the script.
Then see if it works, and for performance move the if (Input.GetMouseButtonDown(0)) up in your code, before you do the raycast, like #Basile said.
Note: This script will work in play-mode on the game-view - not in the editor scene-view.
If you'd like this to work too, you should add [ExecuteInEditMode] above the public class ... line. But be careful with those, it's sometimes hard to stop those scripts :P

making my player sprite land on top of my platform sprite

in my XNA game(im fairly new to XNA by the way) i would like to have my player sprite land on top of a platform. i have a player sprite class that inherits from my regular sprite class, and the regular sprite class for
basic non playable sprite stuff such as boxes, background stuff, and platforms. However, i am unsure how to implement a way to make my player sprite land on a platform.
My player Sprite can jump and move around, but i dont know where and how to check to see if it is on top of my platform sprite.
My player sprites jump method is here
private void Jump()
{
if (mCurrentState != State.Jumping)
{
mCurrentState = State.Jumping;
mStartingPosition = Position;
mDirection.Y = MOVE_UP;
mSpeed = new Vector2(jumpSpeed, jumpSpeed);
}
}
mStartingPosition is player sprites starting position of the jump, and Position is the player sprites current position. I would think that my code for checking to see whether my player sprite is on top of my platform sprite. I am unsure how to reference my platform sprite inside of the playersprite class and inside of the jump method.
i think it should be something like this
//platformSprite.CollisonBox would be the rectangle around the platform, but im not
//sure how to check to see if player.Position is touching any point
//on platformSprite.CollisionBox
if(player.Position == platformSprite.CollisionBox)
{
player.mDirection = 0;
}
Again im pretty new to programming and XNA, and some of this logic i dont quite understand so any help on any of it would be greatly appreciated:D
Thanks
If player.Position is a Point and CollisionBox is a Rectangle, you could use
if (platformSprite.CollisionBox.Contains (player.Position))
I was playing around with something like this just a few days ago.
What you're calling a CollisionBox I called a BoundingBox. A BoundingBox is a Rectangle which represents the area occupied by the sprite.
You'll probably find it helpful to define a BoundingBox for your sprites instead of just using their position.
You can easily test for the collision of Rectangles using the following code:
if (player.BoundingBox.Intersects(platform.BoundingBox)
{
// handle collision here...
}
For this to work, make sure that the X and Y coordinates of your BoundingBox are correctly reflecting your sprite's position.
You may want to look at the Platformer Starter Kit. It includes this as well as detecting when the player is touching an enemy, collecting gems, etc.
The answer about BoundingBox is right, but IMHO it is easier to use Rectangle if you are making a 2D game rather than BoundingBox, wich is designed for a 3D one.
Anyway both objects have intersection / collision test methods that takes Vector2 or Point as parameter.
Now you have to have a box for your player, and a box for your platform. If one collide with the other, you have to check from where (the player can hit the platform from up, down, left, right, or maybe up & left on the left up corner).
If the player is on top of the platform, then just stop his fall, probably by setting his Y-speed component to 0.
Maybe you will need the player to go through the platform when jumping (player hit from bottom) but not when falling (player hit from top).

Categories