I am trying to make a simple weapon change in Unity3D.
The best way to do this is with the mouse Scroll wheel as far as i can see.
I googled on how to do this and found that i have to use the Input.GetAxis("Mouse ScrollWheel"); I use this piece of code and print it. Still i always get an value of 0.
any ideas? I just need to solve how to get the value first, ill figure out the rest myself.
Code idea:
function Update () {
print(WeaponNumber);
if(Input.GetAxis("Mouse ScrollWheel")){
WeaponNumber += Input.GetAxis("Mouse ScrollWheel");
}
}
Hey Friend,
Instead of Input.GetAxis you may use Input.GetAxisRaw. The value for GetAxis is smoothed and is in range -1 .. 1 , however GetAxisRaw is -1 or 0 or 1. and you may remove the If statement. cause when no scrollwheel happens the value is automatically zero.
So, Input.GetAxis("Mouse ScrollWheel") returns 0 if you didn't scroll, 0.1 if you scroll up and -0.1 if you scrolled down. So solution to this code would be:
function Update() {
if (Input.GetAxis("Mouse ScrollWheel") != 0) {
WeaponNumber += Mathf.FloorToInt(Input.GetAxis("Mouse ScrollWheel") * 10));
}
}
And that will basically increase WeaponNumber if you scrolled up and decrease if you scrolled down
Related
I am working on Unity2d Sprite but something is wrong: in my code when I press the jump button my character jump like teleport, it go very fast in the Up direction. The gravity is 9 and my Rigidbody2D mass is 1. My code is this:
if(isGrounded == true && moveH == 0) {
if (Input.GetKeyDown(KeyCode.J)) {
anim.SetBool("str_jump", true);
//rgBody.velocity = new Vector2(0,jumpHeight);
//rgBody.AddForce(Vector2.up * jumpHeight);
transform.position = new Vector2(transform.position.x,
transform.position.y * jumpHeight);
isGrounded = false;
}
}
If your jump is too high, you have to use a variable to modify the height of the jump. In your case, you are using the jumpHeight as the variable to modify the height of your jump.
Decreasing jumpHeight should solve your problem. Note that if jumpHeight is declared as public (public float jumpHeight;), you have to change the variable from the Editor or a function because it will not use the number assigned to it when it was declared. It will use whatever that is assigned to it from the Editor.
For example, when you have public float jumpHeight = 4; but the value is set to 0 in the editor, 0 will be used as the value not 4.
Also you have to use rgBody.AddForce(Vector2.up * jumpHeight);. Uncomment it and then remove the transform.position = new Vector2(transform.position.x,transform.position.y *jumpHeight); line of code.
If this does not solve your problem, then you have to update your question with your complete code.
For a nice jump you could also use rgBody.AddForce((Vector2.up * jumpHeight), ForceMode2D.Impulse); It simulates an impact on your object and you get a nice jump simulation.
Do not forget to declare the public float jumpHeigt = 4f; like "Programmer" said it before.
I hope it will help you.
Simply reducing the jumpHeight value will fix the initial issue of the jump being too high.
However if you want a more realistic 'jump' you may want to utilise Rigidbody2D.velocity simply having rgBody.velocity = new Vector2(rgBody.velocity.x, jumpHeight); should create a nice smooth jump.
If you use the Rigidbody2D.velocity instead of simply changing the transform means that you can alter values such as Gravity Scale and this will make a noticeable difference on the movement of your player. You can play around with different jumpHeight and Gravity Scale values to find what works best for your game.
Use transform.position '+=' instead of just '='. This way you're adding to it's position and not setting it to a certain number(that's why it's teleporting like that). Tho this method only suits horizontal movement in my opinion(if it's a sideview game). For jumping, using AddForce would be way better.
Right now I have 2 Cameras: the main camera displays the gun at its normal state and a second camera is attached to the gun (the gun is a child of the main camera) and when toggled it looks through the scope of the gun and increases the field of view.
Heres a visual for a better understanding:
Now if I were to just toggle the second camera on and turn the main camera off, this would work splendid, but it's not very ideal. You should only have 1 camera per scene.
So I want to Lerp the position of the camera to look through the scope and manually decrease the fieldofview. So I have written the following script:
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
CameraTransform.position = Vector3.Lerp (
CameraTransform.position,
CameraTransform.position + ZoomedTransform.position,
5f * Time.deltaTime
);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
The problem with this is that it doesn't work: when I hit the zoom button, the camera speeds through the scene at the speed of light and it's hard to tell exactly what is going on.
Could anyone give me some insight as to what I'm doing wrong? I think it is something to do with the parent-child relationship, but even when I've tried using static values, I cannot seem to replicate the correct solution.
Hierarchy:
(This answer operates under the assumption that ZoomedTransform is a relative transformation, and not the absolute position of the camera as suspected by 31eee384's answer.)
I think there are a couple issues with your code. I'll tackle them individually so they're easier to understand, but they both relate to the following line:
CameraTransform.position = Vector3.Lerp (CameraTransform.position, CameraTransform.position + ZoomedTransform.position, 5f * Time.deltaTime);
First, let's look at how you're using Vector3.Lerp(). For the third argument of Vector3.Lerp(), you're supplying 5f * Time.deltaTime. What exactly does this value work out to? Well, the standard framerate is about 60 FPS, so Time.deltaTime = ~1/60. Hence, 5f * Time.deltaTime = 5/60 = ~0.0833.
What is Vector3.Lerp() expecting for the third argument, though? According to the documentation, that third argument should be between 0 and 1, and determines whether the returned Vector3 should be closer to the first or second given Vector3. So yes, 5f * Time.deltaTime falls within this range, but no interpolation will occur - because it will always be around ~0.0833, rather than progressing from 0 to 1 (or 1 to 0). Each frame, you're basically always getting back cameraPos + zoomTransform * 0.0833.
The other notable problem is how you're updating the value of CameraTransform.position every frame, but then using that new (increased) value as an argument for Vector3.Lerp() the next frame. (This is a bit like doing int i = i + 1; in a loop.) This is the reason why your camera is flying across the map so fast. Here is what is happening each frame, using the hypothetical result of your Vector3.Lerp() that I calculated earlier (pseudocode):
// Frame 1
cameraPosFrame_1 = cameraPosFrame_0 + zoomTransform * 0.0833;
// Frame 2
cameraPosFrame_2 = cameraPosFrame_1 + zoomTransform * 0.0833;
// Frame 3
cameraPosFrame_3 = cameraPosFrame_2 + zoomTransform * 0.0833;
// etc...
Every frame, zoomTransform * 0.0833 gets added to the camera's position. Which ends up being a really, really fast, and non-stop increase in value - so your camera flies across the map.
One way to address these problems is to have variables that stores your camera's initial local position, zoom progress, and speed of zoom. This way, we never lose the original position of the camera, and we can both keep track of how far the zoom has progressed and when to stop it.
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private Vector3 startLocalPos;
private float zoomProgress = 0;
private float zoomLength = 2; // Number of seconds zoom will take
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
startLocalPos = CameraTransform.localPosition;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
zoomProgress += Time.deltaTime;
CameraTransform.localPosition = Vector3.Lerp (startLocalPos, startLocalPos + ZoomedTransform.position, zoomProgress / zoomLength);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
Hope this helps! Let me know if you have any questions. This answer does ramble a little, so I hope you don't have any trouble getting the important points from it.
Your lerp target is relative to the camera's current position, so it's constantly moving. This is the target you have:
CameraTransform.position + ZoomedTransform.position
This means that as your camera moves to get closer to this position, the camera's new position causes the destination to change. So your camera keeps moving forever.
Your destination should be ZoomedTransform.position. No addition is necessary because position is in world coordinates. (And when you actually need to convert between spaces, check out TransformPoint and similar methods.)
It has been a while since I have done anything in Unity, but I think it is processing the Lerp function at frame time and not at actual time. You will need to call it in another function that is not being processed at frame time.
Alright I'm offically stumped. I've been able to figure out my problems myself in the past but I'm lost on this one.
I'm trying to flip a child sprite's xscale. I want the flip to occur when the child's x position is negative. With the code below, the sprite does flip, every time the sprite reaches negative position, it loops back and forth flipping until reaching positive again.
I've tried numerous variations, but this is the code in it's simplest form. Any help or alternatives would be appreciative.
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
let pin = childNodeWithName(Pin1) as SKSpriteNode!
let guyPoint = guy.convertPoint(guy.position, fromNode: pin)
if guyPoint.x <= 0 {
guy.xScale = -1
}
else {
guy.xScale = 1
}
}
So if it is constantly flipping it's probably an issue of coordinate space. So check to make sure your convertPoint method is accurately returning the point you want. I would use println() to see what's going on there.
Probably what's happening is you want to flip the xScale when the child node is negative in the scene space or something (i.e. when the child is off the screen) but instead guyPoint might be the position of the child in its parent's coordinate space (so relative to the parent).
Also try with and without the else{} part to see if that changes anything.
I am currently having a bit of trouble making objects in my world wrap. It sort of works, but very often objets appear to get stuck on the boundaries. My wrap code is as follows:
// Wrap our position if we are outside of the world bounds
if (this.state.pos.get(0) > 860) {
this.state.pos.set(0, this.state.pos.get(1));
}
else if (this.state.pos.get(0) < 0) {
this.state.pos.set(860, this.state.pos.get(1));
}
if (this.state.pos.get(1) > 640) {
this.state.pos.set(this.state.pos.get(0), 0);
}
else if (this.state.pos.get(1) < 0) {
this.state.pos.set(this.state.pos.get(0), 640);
}
Is there a better way of doing this? Should I use a translation on the object's position vector rather than simply setting it?
Without a jsfiddle it's a bit hard to diagnose, however this might be due to the this.state.old.pos not being set too. If the position (only) is set, then the velocity will be calculated as the difference between the current and the previous positions (in accordance with verlet integration). In that case, you're implicitly giving the body a huge velocity.
I'd recommend adding/subtracting an amount rather than setting, then you can do the same with the old position.
Here's a working example: http://labs.minutelabs.io/Relativistic-Space-Sheep/
With the relevant line of code: https://github.com/minutelabsio/Relativistic-Space-Sheep/blob/master/library/js/mediators/boilerplate.js#L743
I'm trying to make a game where the user is supposed to drag a sprite up and down on the screen, avoiding incoming obstacles. The last answer here helped me to drag the sprite around on the screen, but I want to set a maximum speed the sprite can be moved (and hopefully with a natural-looking acceleration/deceleration), so it doesn't get too easy to avoid the objects.
Does anybody know how I can modify the code to achieve this, or is there another way to to it?
Thanks :)
You'll need to maintain a CGPoint destinationPosition variable which is the location of your finger and use an update loop to modify it's position:
-(void) update:(ccTime) dt
{
CGPoint currentPosition = draggableObject.position.x;
if (destination.x != currentPosition.x)
{
currentPosition.x += (destination.x - currentPosition.x) / 5.0f; // This 5.0f is how fast you want the object to move to it's destination
}
if (destination.y != currentPosition.y)
{
currentPosition.y += (destination.y - currentPosition.y) / 5.0f;
}
draggableObject.postion = currentPosition;
}
In the ifs, you might want to check if the objects are close to each other, rather than exactly the same number to allow for rounding errors.
You just need to have an if statement in whatever schedule updater you are using, like time, or touches, or whatever.
I'm presuming you have x/y velocities? Just inside your update statement, wherever your acceleration is -
if(acceleration.x > 20){
acceleration.x = 20;
}
if(acceleration.y > 20){
acceleration.y = 20;
}