Could you please advise how i would go about using the input touch function in Unity to make an object changes its x direction every time the user tap on the screen. For example, for 2d setting game, an object is moving forward (to the right) in the x position, if the user tap then the object would move backward in the x position (to the left). Sorry no code is produced.
It's simple as your name "tony" :)
What you can do is to make a simple script which'd move your object to left and right. And on screen touch you can easily change its direction by just -1 multiplication.
Simple script that you can attach to your object.
using UnityEngine;
using System.Collections;
public class MoveObject : MonoBehaviour
{
float _limit = 5;
// 1 for right and -1 for left.
float _direction = 1;
// You can call it as speed
float _speed = 0.01f;
void Start ()
{
}
void Update ()
{
transform.position = Vector3.MoveTowards (transform.position, new Vector3 (transform.position.x + _direction, transform.position.y, transform.position.z), _speed);
if (Input.GetMouseButtonDown (0))
_direction *= -1;
}
}
Hope this helps :)
Related
I'm trying to implement a feature similar to HTC Vive's controller with the leap motion on my Unity project. I wanted to generate a laser pointer from the index finger and teleport the Vive's room on the position of the laser (as it's done with the controller). The problem is the latest leap motion (orion) documentation, it's unclear. Any ideas how to do that? More in general, we thought about using HandController but we don't understand where to add the script component.
Thanks!
It's unclear to me whether the problem you're having is getting hand data in your scene at all, or using that hand data.
If you're just trying to get hand data in your scene, you can copy a prefab from one of the Unity SDK's example scenes. If you're trying to integrate Leap into an existing scene that already has a VR rig set up, check out the documentation on the core Leap components to understand what pieces need to be in place for you to start getting Hand data. LeapServiceProvider has to be somewhere in your scene to receive hand data.
As long as you have a LeapServiceProvider somewhere, you can access hands from the Leap Motion from any script, anywhere. So for getting a ray from the index fingertip, just pop this script any old place:
using Leap;
using Leap.Unity;
using UnityEngine;
public class IndexRay : MonoBehaviour {
void Update() {
Hand rightHand = Hands.Right;
Vector3 indexTipPosition = rightHand.Fingers[1].TipPosition.ToVector3();
Vector3 indexTipDirection = rightHand.Fingers[1].bones[3].Direction.ToVector3();
// You can try using other bones in the index finger for direction as well;
// bones[3] is the last bone; bones[1] is the bone extending from the knuckle;
// bones[0] is the index metacarpal bone.
Debug.DrawRay(indexTipPosition, indexTipDirection, Color.cyan);
}
}
For what it's worth, the index fingertip direction is probably not going to be stable enough to do what you want. A more reliable strategy is to cast a line from the camera (or a theoretical "shoulder position" at a constant offset from the camera) through the index knuckle bone of the hand:
using Leap;
using Leap.Unity;
using UnityEngine;
public class ProjectiveRay : MonoBehaviour {
// To find an approximate shoulder, let's try 12 cm right, 15 cm down, and 4 cm back relative to the camera.
[Tooltip("An approximation for the shoulder position relative to the VR camera in the camera's (non-scaled) local space.")]
public Vector3 cameraShoulderOffset = new Vector3(0.12F, -0.15F, -0.04F);
public Transform shoulderTransform;
void Update() {
Hand rightHand = Hands.Right;
Vector3 cameraPosition = Camera.main.transform.position;
Vector3 shoulderPosition = cameraPosition + Camera.main.transform.rotation * cameraShoulderOffset;
Vector3 indexKnucklePosition = rightHand.Fingers[1].bones[1].PrevJoint.ToVector3();
Vector3 dirFromShoulder = (indexKnucklePosition - shoulderPosition).normalized;
Debug.DrawRay(indexKnucklePosition, dirFromShoulder, Color.white);
Debug.DrawLine(shoulderPosition, indexKnucklePosition, Color.red);
}
}
I'm using Windows Vista and Visual Studio 2010. Create a .Net 4 Windows Forms Application. Drop a progress bar on the default form, add code to handle the form load event and do a progressBar1.Value = 100; there.
Start debugging and you see an animation moving the progress bar to 100 in about half a second.
I need 2 progress bars in my project. One is for "global progress" and the second is for "current step progress" so the second goes from 0 to 100 and hen back to 0 for the next step. The problem is that with the progress bar being slow for some of the quick steps it never reaches 100 and it looks weird.
Is there a way to get rid of that animation? In WPF it's OK but I'd rather stay with Windows Forms.
This is just how the Vista/7 progress bar is designed. When you change the value of the progress bar, the bar is animated to that value progressively.
The only way I know of avoiding this problem is to go backwards when updating the progress bar, as follows:
progressBar1.Value = n;
if (n>0)
progressBar1.Value = n-1;
For a more complete discussion see Disabling .NET progressbar animation when changing value?
Building off of Heffernan's tip on going backwards with the progress bar and Reinhart's extension method approach in a related question, I came up with my own solution.
The solution is pretty seamless and successfully handles the issue you will encounter when the value is at Maximum. This extension method to ProgressBar alleviates the lagging that is caused from the progressive animation style present in the WinForms ProgressBar control when running on Windows Vista and 7 (I haven't tested on Windows 8 yet).
public static class ExtensionMethods
{
/// <summary>
/// Sets the progress bar value, without using 'Windows Aero' animation.
/// This is to work around a known WinForms issue where the progress bar
/// is slow to update.
/// </summary>
public static void SetProgressNoAnimation(this ProgressBar pb, int value)
{
// To get around the progressive animation, we need to move the
// progress bar backwards.
if (value == pb.Maximum)
{
// Special case as value can't be set greater than Maximum.
pb.Maximum = value + 1; // Temporarily Increase Maximum
pb.Value = value + 1; // Move past
pb.Maximum = value; // Reset maximum
}
else
{
pb.Value = value + 1; // Move past
}
pb.Value = value; // Move to correct value
}
}
Sample usage:
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressBar.SetProgressNoAnimation(e.ProgressPercentage);
}
You can easily write a custom progress bar to show its value without animation. The following is a simple implementation to show the progress from 0 to 100 and revert to 0.
public class ProgressBarDirectRender : UserControl
{
private int _value;
public int Value
{
get { return _value; }
set
{
if (value < 0 || value > 100)
throw new ArgumentOutOfRangeException("value");
_value = value;
const int margin = 1;
using (var g = CreateGraphics())
{
if (_value == 0)
ProgressBarRenderer.DrawHorizontalBar(g, ClientRectangle);
else
{
var rectangle = new Rectangle(ClientRectangle.X + margin,
ClientRectangle.Y + margin,
ClientRectangle.Width * _value / 100 - margin * 2,
ClientRectangle.Height - margin * 2);
ProgressBarRenderer.DrawHorizontalChunks(g, rectangle);
}
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, ClientRectangle);
}
}
A much simpler answer, as shown here, is to do this:
pbar.Value = value;
pbar.Value = value - 1;
pbar.Value = value;
Explanation:
It animates the PB as it increases, but not while it decreases. And that is why the above hack sppears to 'fix' the problem.
I liked Derek W's answer and I managed to find a solution which supports data binding. I inherited from System.Windows.Forms.ProgressBar and created new bindable property. Otherwise it's the same:
[DefaultBindingProperty("ValueNoAnimation")]
public class NoAnimationProgressBar : ProgressBar
{
/// <summary>
/// Sets the progress bar value, without using 'Windows Aero' animation.
/// This is to work around (hack) for a known WinForms issue where the progress bar
/// is slow to update.
/// </summary>
public int ValueNoAnimation
{
get => Value;
set
{
// To get around the progressive animation, we need to move the
// progress bar backwards.
if (value != Maximum)
Value = value + 1; // Move past
else
{
// Special case as value can't be set greater than Maximum.
Maximum = value + 1;
Value = value + 1;
Maximum = value;
}
Value = value; // Move to correct value
}
}
}
You can bind to the property like this (viewModel has an int property called Value):
var dataSource = new BindingSource { DataSource = _viewModel };
progressBarBindingHack.DataBindings.Add("ValueNoAnimation", dataSource, "Value");
I am having a class inherited from QGraphicsScene. I have a mouseMoveEvent in this class. Based on the mouse move I am sending the co ordinates via signal to the main window. I have multiple GraphicViews in main window. Based on the scene from which the signal is received I am display the scene co ordinates using QGraphicsTextItem.
The problem is when I move out of the scene area I am unable to hide the QGraphicsTextItem.
Can someone give me a work around for this?
Class Scene::QGraphicsScene
{
void MouseMoveEvent(QGraphicsSceneMouseEvent *Event)
{
int XPos = event.x();
int YPos = event.y();
emit SignalPos(XPos,YPos);
}
}
//In Main Window
connect(scene1,SignalPos(int,int),this,SlotPos1(int,int);
//Similarly for scene2,scene3,scene4
void MainWindow::SlotPos(int X, int Y)
{
m_qgtxtItemX.setText(QString::x);
//I want to hide this once I am out of scene.It is a member variable. I tried
//taking local variable but it didn't work.
//Similarly for y and other slots
}
Install an event filter on the scene.
scene1->installEventFilter(this);
then implement the method in the class that is referenced by "this":
bool eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Leave)
{
qDebug() << "Mouse left the scene";
}
return false;
}
Just tried it and it worked! If you are installing the event filter on more than one object, please use "watched" to differentiate between them.
Best,
Problem is:
I have created terrain and I need to fly over terrain with Camera. I added to Camera "Mouse Look" script, RigidBody: usegravity - unchecked and I have added my code in Update method:
float vert = Input.GetAxis("Vertical");
float hor = Input.GetAxis("Horizontal");
if (vert != 0)
{
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(Vector3.forward * flySpeed * vert);
}
else
{
transform.Translate(Vector3.up * flySpeed * vert);
}
}
if (hor != 0)
{
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(Vector3.right * flySpeed * hor);
}
else
{
transform.Translate(Vector3.up * flySpeed* hor);
}
}
if (Input.GetKey(KeyCode.E))
{
transform.Translate(Vector3.up * flySpeed);
}
else if (Input.GetKey(KeyCode.Q))
{
Vector3 v = Vector3.down * flySpeed;
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(v);
}
}
But sometimes then i go down - Q - camera goes through terrain. Why?
Also looks ugly if you are moving with camera forward as low as possible over terrain and camera does not fall through it - it starts to jump. Also why?
Make sure you have a Terrain Collider on your terrain.
In addition to S.Richmonds answer, you can add a character controller or other similar collider-component object to your camera.
See this answer in the unity questions network:
http://answers.unity3d.com/questions/45763/getting-camera-to-not-see-under-the-ground.html
The Update() method in a monobehavior gets called once each fram. Because the rate which update is called is dependent on frame rate, moving an object by a constant value in Update() can result in inconsistant motion. This can be corrected by multiplying a constant speed by Time.deltaTime, which is the time in seconds since the last frame was rendered. This will fix the fallthrough unless flySpeed is set too high (where the change in position each frame is greater than the collider's size). Additionally as suggested above, using a CharacterController without a rigidbody would be better suited to this situation. Rigidbodies are for objects primarily controlled by physics, while the CharacterController is for objects controlled by scripts.
Someone can help me to create a camera like this: http://www.youtube.com/watch?v=8fIoxtJ_FK4&feature=youtu.be&t=1m24s
I know that, they used gyroscope to do this. However, I don't know How did they do with the camera
Thanks a lot!
You can either use the rotation rate or the attitude of the gyroscope. Just update the rotation of your camera based on the gyro. Here is an example code how it could be done.
void Start()
{
Input.gyro.enabled = true;
}
void Update()
{
rotationRate = Input.gyro.rotationRateUnbiased;
angle.x += -rotationRate.x * ROTATION_SPEED;
angle.y += -rotationRate.y * ROTATION_SPEED;
Camera.main.transform.localEulerAngles = angle;
}
The documentation can be found here: http://docs.unity3d.com/Documentation/ScriptReference/Gyroscope.html