Unity offset parallax fails on web builds - 2d

thanks in advance for helping me out.
I'm wrapping up work on a 2D platformer that has a background parallax effect using a texture offset on five different layers. The two cloud layers just have their offset scrolling over time, and the three ground layers scroll based on the camera position. This all works perfectly in Unity and in the PC build and looks great.
However, on the Unity Web Player and webGL builds, instead of the texture wrapping, it looks like this:
I'm new here, so I can't embed images yet it seems
I have no idea what is causing the problem, but instead of wrapping around and acting like a conveyor belt, it just streaks like that. Here is my parallax code:
using UnityEngine;
using System.Collections;
public class sceneryParallax : MonoBehaviour {
[SerializeField]
private Transform cameraTransform;
[SerializeField]
private Renderer renderBGFar;
[SerializeField]
private Renderer renderBGMid;
[SerializeField]
private Renderer renderBGNear;
public float offsetFar;
public float offsetMid;
public float offsetNear;
void Update () {
float xOffset = cameraTransform.position.x;
Vector2 farOffset = new Vector2((xOffset / offsetFar) % 1.0f, 0.0f);
Vector2 midOffset = new Vector2((xOffset / offsetMid) % 1.0f, 0.0f);
Vector2 nearOffset = new Vector2((xOffset / offsetNear) % 1.0f, 0.0f);
renderBGFar.material.mainTextureOffset = farOffset;
renderBGMid.material.mainTextureOffset = midOffset;
renderBGNear.material.mainTextureOffset = nearOffset;
}
}
Also, here is a screen of my texture setup:
Link
Sorry if there are any formatting problems! I really appreciate any help you can offer. If you need more information, let me know!
Thanks!

If your texture wrapping mode is set to clamp, it will reuse the last available pixel. It sounds like texture mode repeat is what you need, opposed to clamping, per the documentation:
This is useful for preventing wrapping artifacts when mapping an image
onto an object and you don't want the texture to tile. UV coordinates
will be clamped to the range 0...1. When UVs are larger than 1 or
smaller than 0, the last pixel at the border will be used. See Also:
Texture.wrapMode, texture assets.

Related

How to get current facing direction vector 2D?

So I am developing a game in 2D in Godot and I want to see a line from the center of my sprite to its facing position. I have the sprite rotating and moving along the rotation direction but when I try to create vector out of that its very wrong. For example the vector line is going from the center of the sprite to near (0,0) position on the screen.
public override void _Draw()
{
Vector2 rotationDirection = new Vector2(Mathf.Cos(sprite.GlobalRotation) , Mathf.Sin(sprite.GlobalRotation)) - sprite.GlobalPosition;
DrawLine(sprite.GlobalPosition, rotationDirection, Colors.Red, 2f);
}
EDIT:
Fixed it it works now.
public override void _Draw()
{
DrawLine(sprite.GlobalPosition, sprite.GlobalPosition + new Vector2(Mathf.Cos(sprite.GlobalRotation), Mathf.Sin(sprite.GlobalRotation)) * 50f, Colors.Red, 2f);
}
A simpler solution would have been to add a Line2D child node. You can see the effect right away in the editor, and there's no need for any maths.
This might also be more efficient, because custom _draw functions don't play nice with Godot's geometry batching.

Looping ground tile as character moves in unity 2D

I am trying to create a ground tile that, once is off screen moves to the forward position in front of the other ground tile that is currently in the screen.
I have barely tried anything in code that would be even slightly useful to add to this question. Could someone point me in the right direction to be able to get this done so I don't have to just duplicate hundreds of tiles?
Thanks!
Attach this scrip on your Tileobject.
using UnityEngine;
public class SpawnTiles : MonoBehaviour {
private Material currentTile;
public float speed;
private float offset;
// Use this for initialization
void Start () {
currentTile = GetComponent<Renderer>().material;
}
// Update is called once per frame
void Update () {
offset += 0.001f;
currentTile.SetTextureOffset ("_MainTex", new Vector2 (offset * speed, 0));
}
}
Edit
This is what you want?
If YES, follow theses steps.
Create > 3D Object > Quad (Resize as you want)
Select your tile sprite:
Texture type = texture
Wrap mode = repeat
Now creat new Material: Create > Material
Select: Shader = Unlit/Texture
Texture select your previous texture.
Drag and drop this Material inside Quadobject.
Adjust tiles at inspector.
Result
Creat new scrip SpawnTiles and attach at Quadobject.
using UnityEngine;
public class SpawnTiles : MonoBehaviour {
private Material currentTile;
public float speed;
private float offset;
// Update is called once per frame
void Update () {
GetComponent<Renderer>().material.mainTextureOffset = new Vector2 (Time.time * speed, 0f);
}
}
Ajust tiles movement speed at inspector.
Finish rename Quadobject as you want.
If you want to only move the back tile to the front, you probably don't need it, but I still highly suggest looking into object pooling.
To detect if a camera can't see the tile, use this: Renderer.isVisible
To move the tile, if all the tiles are the same dimensions, you could just increase it's position.x by the amount you need.
I have found one solution using WorldPointToViewport().
Here is my script:
using UnityEngine;
using System.Collections;
public class groundTilingScript : MonoBehaviour {
Transform ground; //For reference to the transform
Camera cam; //Reference to Main Camera
float groundWidth; //The width of the transform, used for calculating current max x position of transform and next placement x position
private float nextXPos = 0.0f; //Store next x position in variable for easier reading
// Use this for initialization
void Start () {
//Set up References
ground = transform;
cam = Camera.main;
//Store Ground width (Width of the ground tile)
groundWidth = ground.GetComponent<Renderer> ().bounds.size.x;
}
// Update is called once per frame
void Update () {
//Create new Vector3 to be used in WorldToViewportPoint so it doesn't use the middle of the ground as reference
Vector3 boxRightPos = new Vector3 (ground.position.x + groundWidth/2, ground.position.y, ground.position.z);
//Store view Position of ground
Vector3 viewPos = cam.WorldToViewportPoint (boxRightPos);
//If the ground tile is left of camera viewport
if (viewPos.x < 0) {
//gameObject is offscreen, destroy it and re-instantiate it at new xPosition
float currentRightX = ground.position.x + groundWidth;
nextXPos = currentRightX + groundWidth;
Instantiate (gameObject, new Vector3 (nextXPos, ground.position.y, ground.position.z), ground.rotation);
Destroy (gameObject);
}
}
}
NOTE: I have to set up two ground tiles initially to give room for camera to go further than the ground tile. (One tile on screen, one off)
Again, this is just my attempt. I am completely open to criticism.

Scrolling a Tiled Map in Cocos2D

I've got an issue that I simply can't figure out; probably because I don't have the correct knowledge.
I have a TMX map made in Tiled. The Map is bigger than the screen size (tiles are 32x32pixels and there are 100x100 tiles).
What I want to do is to be able to move the map by swiping the screen.
I've looked at various tutorials online and examined the paddle.m example but still can't get it to work.
All the tutorials I've come across all focus on moving a clamped centered sprite around a map...
Again, what I want to do is to be able to move the map by swiping/sliding the screen; much like when scrolling through your iPod or moving a picture around.
Can anyone help?
Here is my ccTouchMoved code
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPointMap = [touch locationInView: [touch view]];
touchPointMap = [[CCDirector sharedDirector] convertToGL: touchPointMap];
touchPointMap = [self convertToNodeSpace: touchPointMap];
CCLOG(#"Touch Point Map %lf, %lf", touchPointMap.x, touchPointMap.y);
self.position = CGPointMake(touchPointMap.x, touchPointMap.y);
}
To illustrate the problem I'm seeing on screen when I swipe the screen using the code above:
It seems that if I touch the center of the screen, the bottom left corner of the map will jump to that touched coordinate and will move with my touch until my touch is lifted.
The Map's bottom left corner will always move to where I begin my touch.
Also while the map is being moved, it flashes like crazy and if moved excessively, disappears entirely.
Thanks again All, much appreciated.
Best and Kind Regards,
hiro
I found the solution to the problem.
There's a very bright person in the Cocos2D community who has written a controller to not only pan around organically, but zoom in and out.
Link to Controller, example and preview movie
You wont need to write your touchBegan, Moved and End methods; this Controller does it all for you.
My init
self.theMap = [CCTMXTiledMap tiledMapWithTMXFile: #"city_map.tmx"];
self.bgLayer = [theMap layerNamed:#"bg"];
// boundingRect is the area you wish to pan around
CGRect boundingRect = CGRectMake(0, 0, 32*50, 16*50);
theMap.anchorPoint = ccp(0,0);
[self addChild: theMap z: -1];
// _controller is declared in the #interface as an object of CCPanZoomController
_controller = [[CCPanZoomController controllerWithNode:self] retain];
_controller.boundingRect = boundingRect;
_controller.zoomOutLimit = _controller.optimalZoomOutLimit;
_controller.zoomInLimit = 2.0f;
[_controller enableWithTouchPriority:0 swallowsTouches:YES];

how to do 3D rotation around center in AS3 using matrix3D?

I am trying to rotate a Sprite in three dimensions around its centerpoint, and I am struggling to understand some of the behavior of matrix3D.
Ive overridden the set rotationX, rotationY, and rotationZ methods of the Sprite as follows:
override public function set rotationX (_rotationX:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationX, Vector3D.X_AXIS);
this.transform.matrix3D.prependRotation(_rotationX, Vector3D.X_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
override public function set rotationY (_rotationY:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationY, Vector3D.Y_AXIS);
this.transform.matrix3D.prependRotation(_rotationY, Vector3D.Y_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
override public function set rotationZ (_rotationZ:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationZ, Vector3D.Z_AXIS);
this.transform.matrix3D.prependRotation(_rotationZ, Vector3D.Z_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
I am using prependTranslation to correct the centerpoint of the rotation, and the first prependRotation to cancel out any previously-applied rotation.
Testing it out, rotationX works exactly as expected, and the Sprite rotates around its horizontal axis.
rotationY and rotationZ also appear to work fine. However, there is one problem: whenever rotationY or rotationZ are set, all of the other rotation values change as well. This is not a problem with rotationX -- if I set rotationX, nothing else changes. But if I set rotationY or rotationZ all the rotation values change, which is a problem for my app (which is trying to save and restore values).
I think I am just lacking some understanding about what is going on with matrix3D. How can I implement this so there is no interdependence between the values?
Another easy solution is to add the object and center it within a container sprite and do the 3D transformations on the containing sprite.
I know nothing about AS3 etc. But just looking at your code, I wonder why you translate on the z-axis using what I understand to be x and y values (width and height). Shouldn't the z-axis be translated using something like "depth"?
This is very simple, you can try use the following code:
var matrix3d:Matrix3D = s.transform.matrix3D;
matrix3d.appendRotation( -1, Vector3D.Z_AXIS , new Vector3D( 390, 360, 0 ) );
while s is your sprite, the third parameter, Vector3D indicate your sprite's center position.
The Above code will make the sprite s rotate more -1 degree.

rotating centered content

Ok, so I've been trying to get this concept to work for the day now and have had zero luck. I am not so good with math, so any help will be appreciated. I am trying to rotate a centered container from it's center. The problem with this code is when I use the rotatePicture method, it doesn't rotate from the center, instead it rotates from the box's top-left corner. Here's the code...
import mx.effects.Rotate;
private function init():void
{
calculateCoordinates();
}
private function rotateBox():void
{
var m:Matrix = myBox.transform.matrix;
var centerX:Number = myBox.width / 2;
var centerY:Number = myBox.height / 2;
var centerPoint:Point = new Point(centerX, centerY);
var transformPoint:Point= m.transformPoint(centerPoint);
m.translate(-transformPoint.x, -transformPoint.y);
m.rotate(90 * Math.PI / 180);
m.translate(transformPoint.x, transformPoint.y);
myBox.transform.matrix = m;
this.callLater(calculateCoordinates);
//calculateCoordinates();
}
private function calculateCoordinates():void
{
var x : Number = (myBox.parent.width - myBox.width) / 2;
x = x < 0 ? 0 : x;
var y : Number = (myBox.parent.height - myBox.height) / 2;
y = y < 0 ? 0 : y;
myBox.move(x, y);
}
Ok, this was a bit tricky and i'm working out a couple of details, but in case anyone had a similar issue, I found the general answer. Just took a movie break to refresh the brain...
I had to place a variable for how many turns the canvas had rotated which was easy since I was restricting the degrees to only 90. Then I place in a switch statement that tested the turns variable and recalculated the (x,y) coordinates based off of the turns. Since I knew that the Rotate class would create a cooler effect and end with the same result, I ended up using that instead.
Cheers!
I don't know what your background is, but in my experience this is a classic case of "out-thinking yourself".
You've written quite a bit of code to do something that is actually native to the Flash display API's.
Since you seem to be using Flex I'll just tell you that the simple way to achieve this is to dynamically reposition your display clip contents so that the center of your contents is at the 0,0 point of your clip.
This gets harder the more content you have, but if you just have something like an image or a button or what have you, it's really easy to just calculate the height and width, then divide by 2 and subtract.
Then the rotation property will work just fine.
In Flash it's even easier because you can just make a new clip, bind your class to the clip, and place all yours contents in the Flash authoring tool positioned properly for rotation to work as expected.
Yeah, what Back2Dos said.
Personally, I'd wrap the container in another sprite, position it so its center is at (0,0) in that sprites coordinate space, and then just rotate the sprite ... it's simple and robust ...
I'd like to use <s:Rotate> to rotate center. Hope useful to you.

Resources