How do I properly calibrate the accelerometer for my iPhone game? Currently, when the phone is on a flat surface, the paddle drifts to the left. High or Low Pass filters are not an acceptable solution as I need complete control over the paddle even at low & high values. I know Apple has the BubbleLevel sample but I find it difficult to follow... could someone simplify the process?
My accelerometer code looks like this:
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
float acelx = -acceleration.y;
float x = acelx*40;
Board *board = [Board sharedBoard];
AtlasSprite *paddle = (AtlasSprite *)[board.spriteManager getChildByTag:10];
if ( paddle.position.x > 0 && paddle.position.x < 480) {
paddle.position = ccp(paddle.position.x+x, paddle.position.y);
}
if ( paddle.position.x < 55 ) {
paddle.position = ccp(56, paddle.position.y);
}
if ( paddle.position.x > 435 ) {
paddle.position = ccp(434, paddle.position.y);
}
if ( paddle.position.x < 55 && x > 1 ) {
paddle.position = ccp(paddle.position.x+x, paddle.position.y);
}
if ( paddle.position.x > 435 && x < 0) {
paddle.position = ccp(paddle.position.x+x, paddle.position.y);
}
}
Thank you!
Okay, problem SOLVED and the solution is so simple I'm actually embarrassed I didn't come up with it sooner. It's as simple as this:
In a "Calibration Button":
//store the current offset for a "neutral" position
calibration = -currentAccelX * accelerationFactor;
In the game time accelerometer function:
//add the offset to the accel value
float x = (-acceleration.y * accelerationFactor) + calibration;
It's as simple as adding the offset. * hides his head *
This is the code I have so far:
//calibrate code from StackOverflow
float calibration = -acceleration.x * accelerationFraction;
float x = (-acceleration.y * accelerationFraction) + calibration;
//My original code
accelerationFraction = acceleration.y*2;
if (accelerationFraction < -1) {
accelerationFraction = -1;
} else if (accelerationFraction > 1) {
accelerationFraction = 1;
}
//API CHANGE set delegate to self
if (orientation == UIDeviceOrientationLandscapeLeft){
accelerationFraction *= -1;
}
Related
I am having an application in which I have to increase android brightness using the swipe up and down but the issue is I want to increase the brightness continuously If I scroll up and decrease also if I scroll down. My code is
if(t.phase == TouchPhase.Ended)
{
//save ended touch 2d point
secondPressPos = new Vector2(t.position.x,t.position.y);
//create vector from the two points
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
//normalize the 2d vector
currentSwipe.Normalize();
//swipe upwards
if(currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
if(Brightness >= 1.0f)
{
Brightness = 1.0f;
}
else if (Brightness <= -1.0f){
Brightness = 0.0f;
}
else{
Brightness = Brightness + 0.2f;
}
}
}
This code works only If I want to increase or decrease the brightness by some value but then I have to swipe again which I don't want.
I would simply not normalize the vector but rather use it as a factor like e.g.
// Configure some threshold (in pixels) the user has to swipe before changing the brightness
[SerializeField] private float THRESHOLD = 0f;
// Since the position change is in pixels of the display
// configure here how this movement is mapped into your brightness change
[SerializeField] private float SENSITIVITY = 0.01f;
private void Update()
{
if(Input.touchCount < 1) return;
var t = Input.GetTouch(0);
switch (t.phase)
{
case TouchPhase.Began:
firstPressPos = t.position;
break;
case TouchPhase.Moved:
secondPressPos = t.position;
var currentSwipe = secondPressPos - firstPressPos;
if(Mathf.Abs(currentSwipe.x) < 0.5f && Mathf.Abs(currentSwipe.y) > THRESHOLD)
{
// remove the threshold amount
currentSwipe.y -= Mathf.Sign(currentSwipe.y) * THRESHOLD;
// Smooth change the brightness instead of stepwise
// depending on how far the user swiped
Brightness += currentSwipe.y * SENSITIVITY;
// Sanatize value between 0 and 1
Brightness = Mathf.Clamp(Brightness, 0, 1);
}
break;
}
}
i want to rotate (actually just to the left and right side) an object by swiping over the screen. I have working code already but when i swipe from the left to the right of my screen, the whole movement is kind of lagging.
The object has the following script.
Any help is appreciated... this is driving me crazy.
Thank you for your time!
[ICODE]void Update()
{
if (Input.touchCount == 0)
{
oldTouchPositions[0] = null;
oldTouchPositions[1] = null;
}
else if (Input.touchCount == 1)
{
if (oldTouchPositions[0] == null || oldTouchPositions[1] != null)
{
oldTouchPositions[0] = Input.GetTouch(0).position;
oldTouchPositions[1] = null;
}
else
{
Debug.Log("Dragging Detected");
Vector2 newTouchPosition = Input.GetTouch(0).position;
float dis = (Vector2.Distance((Vector2)oldTouchPositions[0], newTouchPosition)) / 4;
if (((Vector2)oldTouchPositions[0])[0] < newTouchPosition[0])
{
//Debug.Log("Left"); dunno if correct
vertical = (vertical - velcoidadeDeGiro * dis) % 360;
transform.localRotation = Quaternion.AngleAxis(vertical, Vector3.up);
oldTouchPositions[0] = newTouchPosition;
}
else
{
//Debug.Log("Right");
vertical = (vertical - velcoidadeDeGiro * dis) % 360;
transform.localRotation = Quaternion.AngleAxis(vertical, Vector3.down);
oldTouchPositions[0] = newTouchPosition;
}
}
}[/ICODE]
I'm a unity3d learner. I have a problem with rotation of an object. I want to rotate objects about 40 degrees along the z axis. If the objects rotation has reached 40 degrees, I want something to happen. Here is my code.
foreach(Touch touch in Input.touches) {
if(touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) {
var target = Quaternion.Euler (0, 0,-40);
transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);
if (transform.rotation.eulerAngles.z == -40) {
toggle = true;
speech = "blah blah blah";
snake = man;
}
}
}
The if(transform.rotation.eulerAngles.z == -40) line of code is not working. So I don't know if the rotation degree has reached 40 degree or not. How do I check if the rotation degree has reached 40 degrees?
I don't understand your code intent.
EulerAngles is not set negative only positive value(Vector3)
-if(eulerAngles.z == -40) is not work you try change value -40 -> 320
If you want scenario ontouch -> object rotation -> event
try this code.
float rotTime = 1f; // rotation duration
Vector3 rotValue = new Vector3(0, 0, -40f); // rotation value
void Update () {
foreach (Touch touch in Input.touches)
if (touch.phase == TouchPhase.Began) OnTouchEvent();
}
void OnTouchEvent()
{
StopCoroutine("rotationCoroutine");
StartCoroutine("rotationCoroutine");
}
IEnumerator rotationCoroutine()
{
float startTime = Time.time;
Vector3 startRot = transform.eulerAngles;
Vector3 endRot = startRot;
endRot += rotValue;
while (Time.time - startTime <= rotTime)
{
transform.eulerAngles = Vector3.Slerp(startRot, endRot,(Time.time - startTime) / rotTime);
yield return null; // wait 1 frame
}
//rotation end
MyAction();
}
void MyAction()
{
Debug.Log("rotation end");
//toggle = true;
//speech = "blah blah";
//snake = man;
}
Good Luck :D
I was wondering if there's a way to add (in my case) 120 degrees everytime I push 'ButtonA', and subtract 120 degrees everytime I push 'ButtonB', from the Z-axis rotation of a 2d sprite (prefab).
This is the code I'm using at the moment, but it only rotates once left, and once right:
function TouchOnScreen ()
{
if (Input.touchCount > 0)
{
var touch = Input.touches[0];
if (touch.position.x < Screen.width/2)
{
var RSpeed = 10.0f
transform.rotation = Quaternion.Lerp ( transform.rotation,Quaternion.Euler(0,0,120), Time.deltaTime*RSpeed);
Debug.Log("RotateRight");
}
else if (touch.position.x > Screen.width/2)
{
var LSpeed = 10.0f
transform.rotation = Quaternion.Lerp ( transform.rotation,Quaternion.Euler(0,0,-120), Time.deltaTime*LSpeed);
Debug.Log("RotateLeft");
}
}
}
Thanks in advance!
Note: Please use unityscript if you can, I'm pretty new to coding and unityscript is all I know so far.
From the online documentation it is shown that the signature of the function is
static function Lerp(from: Quaternion, to: Quaternion, t: float): Quaternion;
that means the second parameter is the new rotation of the object not the rotation offset
you should use something of the sort
function TouchOnScreen ()
{
if (Input.touchCount > 0)
{
var touch = Input.touches[0];
if (touch.position.x < Screen.width/2)
{
var RSpeed = 10.0f
transform.rotation = Quaternion.Lerp ( transform.rotation,transform.rotation + Quaternion.Euler(0,0,120), Time.deltaTime*RSpeed);
Debug.Log("RotateRight");
}
else if (touch.position.x > Screen.width/2)
{
var LSpeed = 10.0f
transform.rotation = Quaternion.Lerp ( transform.rotation,transform.rotation + Quaternion.Euler(0,0,-120), Time.deltaTime*LSpeed);
Debug.Log("RotateLeft");
}
}
}
note the second parameter is transform.rotation + Quaternion.Euler(0,0,120) (current rotation + offset to the right)
I'm not an expert on unity engine (I only started toying with the free version yesterday, literally)
Try this one
function TouchOnScreen ()
{
if (Input.touchCount > 0)
{
var touch = Input.touches[0];
if (touch.position.x < Screen.width/2)
{
var RSpeed = 10.0f
transform.Rotate(0,0,120);
Debug.Log("RotateRight");
}
else if (touch.position.x > Screen.width/2)
{
var LSpeed = 10.0f
transform.Rotate(0,0,-120);
Debug.Log("RotateLeft");
}
}
}
If this not works try with Gameobject. I didn't check this
im writing a game to find the differences between 2 images. i created a subclass of CCSprite, Spot. firstly i tried to create small images and add itself according to it's position, but later i found the position is hard to determine, since it's hard to avoid offset of 1 or 2 pixels.
then i tried to make the Spot the same size as the image, with the other part transparent. but I still need to find out the 'hotspot' of finger tap. but when i use CGRectContainsPoint([self boundingBox], touchLocation), it's actually the whole image.
so is there any other way to do this? like content.size or self.size, and make a CGRect out of it's non-transparent part?
Thank you.
I figured it out now. here is my code: (it's actually quite simple
-(void) findRect:(NSString*) fn {
//the origin of mTex is top left
//the origin of CGRect is top left, in the coordinate system inside the image
int topLeftX = 0;
int topLeftY = 0;
for (int i = 0; i < image_width; i += 10) {
for (int j = 0; j < image_height; j += 10) {
if (([mTex pixelAt:ccp(i, j)].a & 0xFF) != 0) {
topLeftX = i;
topLeftY = j;
goto outer;
}
}
}
outer:;
int topRightX = 0;
for (int i = topLeftX; i < image_width; i += 10) {
if (([mTex pixelAt:ccp(i, topLeftY)].a & 0xFF) == 0) {
topRightX = i;
break;
}
}
if (topRightX == 0) {
topRightX = image_width - 1;
}
int bottomLeftY = 0;
for (int i = topLeftY; i < image_height; i += 10) {
if (([mTex pixelAt:ccp(topLeftX, i)].a & 0xFF) == 0) {
bottomLeftY = i;
break;
}
}
if (bottomLeftY == 0) {
bottomLeftY = image_height - 1;
}
areaRect = CGRectMake(topLeftX, topLeftY, topRightX - topLeftX, bottomLeftY - topLeftY);
}