0
\$\begingroup\$

I am trying to replicate the endless scrolling of slither.io but, I can't figure out how to implement it. Since the players can move to any direction and the background needs to be available during player's displacement.

All the parallax background scrolling tutorials show only moving on one axis, either x or y, but my case it could be to any possible direction like an arrow compass.

Can some one point me in the right direction about how I can implement this effect?

EDIT: User can move to any possible direction like an arrow in a compass. enter image description here

Custom Camera Controller that follows the player

public class CameraController : MonoBehaviour {

    public GameObject Player;

    private Vector3 offset;

    // Use this for initialization
    void Start () {

        offset = transform.position - Player.transform.position;
    }

    // Update is called once per frame
    void LateUpdate () {

        transform.position = Player.transform.position + offset;
    }
}
\$\endgroup\$
  • \$\begingroup\$ What have you tried so far? Where is it misbehaving? \$\endgroup\$ – DMGregory Oct 31 '18 at 23:09
  • \$\begingroup\$ I am confused, since I tried the scene like a horizontal endless scrolling, then I realized that the player moves to any direction. I don't know how to implement it. \$\endgroup\$ – Carlos Oct 31 '18 at 23:13
  • \$\begingroup\$ One simple solution would be to have a background that is tileable both on Y and X axis, then when the player moves out of bounds, place the background there to tile it, did you try that? \$\endgroup\$ – TomTsagk Nov 1 '18 at 11:41
  • 1
    \$\begingroup\$ Unity has some tutorials about this. Be sure to check them out first. Your keywords are: unity infinite background \$\endgroup\$ – John Hamilton Nov 1 '18 at 12:08
  • \$\begingroup\$ I have been experimenting all kind of Unity tutorials of background scrolling, but all of them show horizontal or vertical scrolling. My issue is based on multidirectional movement. Player can move to any given direction. N,S, E,W, NE, NW, etc. It is like having a compass arrow, it can point out to any direction. \$\endgroup\$ – Carlos Nov 1 '18 at 12:49
2
\$\begingroup\$

Myself, I'd solve this in a shader.

We can make a shader that offsets our wrapping background texture based on where the object is positioned in the scene.

Then we can apply this to a material on a quad that's parented to our camera.

As our camera moves around the world, it will never move past the edge of the background quad, since the quad is a child that moves with the camera.

Instead, as the camera moves, it shifts the position where we're rendering the background quad, which offsets its texture lookups accordingly in the shader.

Here's a shader that can do this:

Shader "Unlit/ParallaxTexture"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        // Add a variable to control how quickly the parallax scrolls as we move in x & y.
        _ScrollRatio ("Scroll Ratio", Vector) = (1, 1, 0, 0)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // I removed the lines relating to fog.
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _ScrollRatio;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                // Shift the texture according to our position in the world.
                o.uv.x += unity_ObjectToWorld[0].w * _ScrollRatio.x;
                o.uv.y += unity_ObjectToWorld[1].w * _ScrollRatio.y;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ I tried your approach but it doesn't work since I have a CameraController that follows the player. Any idea how to overcome this? \$\endgroup\$ – Carlos Nov 1 '18 at 14:47
  • \$\begingroup\$ I don't observe any reason the CameraController script you've shown should interfere with this. If you parent the quad to the camera, so that the quad moves along with the camera, then it should not matter what scripts are moving the camera - the quad will simply follow automatically. Try telling us more about the specific symptoms you're observing. "Doesn't work" is never enough information to diagnose the error. \$\endgroup\$ – DMGregory Nov 1 '18 at 14:52
  • \$\begingroup\$ It works. I was using an old reference to my material, I just forgot that the new one got the shader. Thanks so much. \$\endgroup\$ – Carlos Nov 1 '18 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.