#StackBounty: #unity #lighting Moving directional light cause huge fps drop: why?

Bounty: 50

I’ve implemented a simple script to simulate Sun Rotation (day/night cycle).

In my “Update” i Rotate main Directional Light (the sun).
What i’ve noticed is that my FPS dropped from 60 to 20-25 fps.

I can understand why: recalculate all light each frame can be (euphemism) cpu-consuming.

So i switched approach using an InvokeRepeating with a repeating time of 0.25f seconds (4 “movement” per second).

Also with this approach my frame rate drop from 60 to 50 (unacceptable).

So my question is : is there a way to move/rotate a light (simulating a day/night cycle for instance) without meet a so big fps-dropping but mantaining realism ?

Thanks


Get this bounty!!!

#StackBounty: #unity #keyboard #monitor #multimedia #gnome-power-manager How to use keyboard keys without ending IDLE_MODE_BLANK?

Bounty: 50

I want to change the volume without waking my laptop display up.

This question wants to accomplish the same but has no usable answer (turning it off again is not an option as the environment is light-sensitive, the display has to stay off the entire time)

As display wakeup seems to be managed by gnome-power-manager I read this
which pointed me at IDLETIME
which seems to be managed by gnome-idle-monitor….
which left me without leads as my C is too bad.


So to summarize: I want to be able to use some specific keys on my keyboard (e.g. volume keys) without resetting the IDLETIME counter ->
resulting in gnome not waking up my display)

How can I accomplish this?


Update: I don’t care about the way (preventing IDLETIME reset / some other obscure dark magic), for me only the result – display staying off – matters.


Get this bounty!!!

#StackBounty: #unity #shaders #unity-shader-graph Unity LWRP & Projection Shader

Bounty: 50

I recently added the Lightweight Render Pipeline to my project as I’d like to start experimenting with Shadergraph to see if I can get a better basic understanding of shaders.

Everything has gone pretty smoothly except the Shader used by my Projectors, the Projection Shader Standard asset no longer works (does not project the texture) and I have very little experience with Shaders.

The main concern for me is that I cannot find anyone else who seems to be having this problem.

I have tried reading through the older shader and recreating it in ShaderGraph but I’m out of my depth.

So could anyone provide me with a simple projection shader or materials on where I could learn to write one, or just learn more about them projection specifically.

thanks

edit: To clarify I was using the Projectors to project a simple square texture on to each tile that I could tint, to show selectable/current/target tiles.
Picture of Old Setup

Old shader that no longer works under Lightweight Render Pipeline From DevGuy @ Unity Forums

// Upgrade NOTE: replaced '_Projector' with 'unity_Projector'
// Upgrade NOTE: replaced '_ProjectorClip' with 'unity_ProjectorClip'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

  Shader "Projector/AdditiveTint" {
     Properties {
       _Color ("Tint Color", Color) = (1,1,1,1)
       _Attenuation ("Falloff", Range(0.0, 1.0)) = 1.0
       _ShadowTex ("Cookie", 2D) = "gray" {}
     }
     Subshader {
       Tags {"Queue"="Transparent"}
       Pass {
         ZWrite Off
         ColorMask RGB
         Blend SrcAlpha One // Additive blending
         Offset -1, -1

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #include "UnityCG.cginc"

         struct v2f {
           float4 uvShadow : TEXCOORD0;
           float4 pos : SV_POSITION;
         };

         float4x4 unity_Projector;
         float4x4 unity_ProjectorClip;

         v2f vert (float4 vertex : POSITION)
         {
           v2f o;
           o.pos = UnityObjectToClipPos (vertex);
           o.uvShadow = mul (unity_Projector, vertex);
           return o;
         }

         sampler2D _ShadowTex;
         fixed4 _Color;
         float _Attenuation;

         fixed4 frag (v2f i) : SV_Target
         {
           // Apply alpha mask
           fixed4 texCookie = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
           fixed4 outColor = _Color * texCookie.a;
           // Attenuation
           float depth = i.uvShadow.z; // [-1 (near), 1 (far)]
           return outColor * clamp(1.0 - abs(depth) + _Attenuation, 0.0, 1.0);
         }
         ENDCG
       }
     }
  }


Get this bounty!!!

#StackBounty: #unity #cinemachine Free camera pan and zoom with Cinemachine2D

Bounty: 50

I’m starting to use Cinemachine2D for a 2D game were you can freely pan and zoom the world.

I set a confiner component to the virtual camera, and the collider is effectively the entire world. There is no player to follow – instead, the player presses the WASD keys and to move the virtual camera’s transform around the map (hence it pans).

This works. The camera will not go beyond the bounds of the world.

The problem is that if the player presses the W key (go pan up), the Y position of the virtual camera keeps going up even though the camera is hitting the collider bounds. Visually, this doesn’t matter. However, if the player decides to pan down (pressing the S key), it will take a while before the camera can start moving down, because the Y position is fairly high since the player was holding the W key originally.

The solution to this is for me to manually calculate when to deny the WASD keys so that the transform position won’t go beyond the world’s bounds. However, this seems a bit odd as I feel Cinemachine2D was designed to solve specifically this kind of situation, so I decided to ask here and check if I’m doing something wrong.

On a similar vein, the player can also scroll the mouse wheel to zoom in and out. I do this by changing the orthographic size of the virtual camera. It works, but if the player zooms out too much it of course starts to see “outside the world”, whereas I’d like to deny that extra zoom out.

Again, those two cases are things I suppose I could compute myself, but I have the feeling that Cinemachine2D was meant to address these cases.

How can I solve these situations with Cinemachine2D?


Get this bounty!!!

#StackBounty: #unity Adding functionality to make individual anchor points of bezier continuous or non-continuous

Bounty: 50

I am creating bezier curves with the following code. The curves can be extended to join several bezier curves by shift clicking in the scene view.
My code has functionality for making the whole curve continuous or non-continuous. I realised that I need to make individual points (specifically anchor points) have this functionality.

I believe the most ideal way to go about this is creating a new class for the points with this functionality (making points continuous or non-continuous) since this can be used to add other properties that might be specific to the points. How can do this?

Path

[System.Serializable]
public class Path {

[SerializeField, HideInInspector]
List<Vector2> points;

[SerializeField, HideInInspector]
public bool isContinuous;

public Path(Vector2 centre)
{
    points = new List<Vector2>
    {
        centre+Vector2.left,
        centre+(Vector2.left+Vector2.up)*.5f,
        centre + (Vector2.right+Vector2.down)*.5f,
        centre + Vector2.right
    };
}

public Vector2 this[int i]
{
    get
    {
        return points[i];
    }
}

public int NumPoints
{
    get
    {
        return points.Count;
    }
}

public int NumSegments
{
    get
    {
        return (points.Count - 4) / 3 + 1;
    }
}

public void AddSegment(Vector2 anchorPos)
{
    points.Add(points[points.Count - 1] * 2 - points[points.Count - 2]);
    points.Add((points[points.Count - 1] + anchorPos) * .5f);
    points.Add(anchorPos);
}

public Vector2[] GetPointsInSegment(int i)
{
    return new Vector2[] { points[i * 3], points[i * 3 + 1], points[i * 3 + 2], points[i * 3 + 3] };
}

public void MovePoint(int i, Vector2 pos)
{

    if (isContinuous)
    { 

        Vector2 deltaMove = pos - points[i];
        points[i] = pos;

        if (i % 3 == 0)
        {
            if (i + 1 < points.Count)
            {
                points[i + 1] += deltaMove;
            }
            if (i - 1 >= 0)
            {
                points[i - 1] += deltaMove;
            }
        }
        else
        {
            bool nextPointIsAnchor = (i + 1) % 3 == 0;
            int correspondingControlIndex = (nextPointIsAnchor) ? i + 2 : i - 2;
            int anchorIndex = (nextPointIsAnchor) ? i + 1 : i - 1;

            if (correspondingControlIndex >= 0 && correspondingControlIndex < points.Count)
            {
                float dst = (points[anchorIndex] - points[correspondingControlIndex]).magnitude;
                Vector2 dir = (points[anchorIndex] - pos).normalized;
            points[correspondingControlIndex] = points[anchorIndex] + dir * dst;
                }
            }
        }
    }

    else {
         points[i] = pos;
    }
}

PathCreator

public class PathCreator : MonoBehaviour {

[HideInInspector]
public Path path;


public void CreatePath()
{
    path = new Path(transform.position);
}
}

PathEditor

[CustomEditor(typeof(PathCreator))]
public class PathEditor : Editor {

PathCreator creator;
Path path;

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();
    EditorGUI.BeginChangeCheck();

    bool continuousControlPoints = GUILayout.Toggle(path.isContinuous, "Set Continuous Control Points");
    if (continuousControlPoints != path.isContinuous)
    {
        Undo.RecordObject(creator, "Toggle set continuous controls");
        path.isContinuous = continuousControlPoints;
    }

    if (EditorGUI.EndChangeCheck())
    {
        SceneView.RepaintAll();
    }
}

void OnSceneGUI()
{
    Input();
    Draw();
}

void Input()
 {
    Event guiEvent = Event.current;
    Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin;

    if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift)
    {
        Undo.RecordObject(creator, "Add segment");
        path.AddSegment(mousePos);
    }
}

void Draw()
{

    for (int i = 0; i < path.NumSegments; i++)
    {
        Vector2[] points = path.GetPointsInSegment(i);
        Handles.color = Color.black;
        Handles.DrawLine(points[1], points[0]);
        Handles.DrawLine(points[2], points[3]);
        Handles.DrawBezier(points[0], points[3], points[1], points[2], Color.green, null, 2);
    }

    Handles.color = Color.red;
    for (int i = 0; i < path.NumPoints; i++)
    {
        Vector2 newPos = Handles.FreeMoveHandle(path[i], Quaternion.identity, .1f, Vector2.zero, Handles.CylinderHandleCap);
        if (path[i] != newPos)
        {
            Undo.RecordObject(creator, "Move point");
            path.MovePoint(i, newPos);
        }
    }
}

void OnEnable()
{
    creator = (PathCreator)target;
    if (creator.path == null)
    {
        creator.CreatePath();
    }
    path = creator.path;
}
}


Get this bounty!!!

#StackBounty: #unity #movement Emulating the movement of a differential drive robot

Bounty: 100

I want to emulate the movements of an Khepera-like roboter (so a differntial drive robot) using Unity. It has two engines, the engine speed is set over the network by RPC magic which ends up calling the function move(). That function calculates the desired acceleration and saves it in a member variable.

FixedUpdate() then tries to accelerate up/down to the desired speed and by the desired rotation on each frame. To not mess with the general physic engine I am not setting those values directly but am using AddRelativeForce() and AddRelativeTorque(). However I have two problems:

  • on a change of the desired velocity (the setpoint basically) the movement becomes very jerky. That is expected because the code doesn’t try to ensure a smooth transation, as a linear interpolation would do. I’m not sure how I could do that while continuing to use AddRelative{Torque|Force}().
  • The bigger problem is that the movement is wrong. The basic kinds of movement seem to work[1]. However when trying to driving in a cirlce (i.e. a steady Move(vL = 100, vR = 75), the green line) the robot moves completely irrational and I’m not sure why that is the case.

My code is as follows, some parts ommited for clarity:

private Vector3 acceleration;
private float phi;
public const float R = 0.5f;
public const float L = 1f;

// FixedUpdate  is called once per frame, before the physics engine starts
void FixedUpdate()
{
    /* ... */

    /* move. During the tests accelerating maximally lead to the following
     * maximal acceleartion:
     * sqrt(11.2^2+0.7^2+0.7^2) = 11.24366488294630737835
     *
     * So let's say 15 is the maximal value that can be set via the controller.
     * Currently there's weird shit happening where after the robot rotated it moves
     * extremly fast, so cap the maximal applied acceleration.*/
    const float MAX_ACCELEARTION = 15;

    /* As AccelerateTo() multiplies by the framerate (to get a smooth movement independent
     * of it) small accelerations such as (0.00558295, -0.00144335, 0.00295163) will lead
     * to an de-acceleartion of (-0.3, 0.1, -0.1) so that the robot stands still. However
     * that often overshoots.
     * So if the robot should not accelerate and the current acceleration is very small,
     * don't use AccelerateTo() but just modify it directly (though this is a kinda ugly
     * hack, an PID controller would lead to more realistic behaviour)
     */
    if (acceleration.Equals(new Vector3()) && rb.velocity.sqrMagnitude < Constants.DBL_EPSILON) {
        rb.velocity = new Vector3();
    } else {
        AccelerateTo(rb, acceleration, MAX_ACCELEARTION);
    }
    acceleration = acceleration * (1 - Time.deltaTime);

    /* rotate according to angles */
    rb.AddRelativeTorque(new Vector3(0, (phi * 180 / Mathf.PI) * Time.deltaTime * 5, 0), ForceMode.VelocityChange); // Force, Impulse
    phi = phi * (1 - Time.deltaTime);
}

/**
 *  https://gamedev.stackexchange.com/a/113203
 */
private void AccelerateTo(Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
    Vector3 deltaV = targetVelocity - body.velocity;
    Vector3 accel = deltaV / Time.deltaTime;

    if (accel.sqrMagnitude > maxAccel * maxAccel)
    {
        accel = accel.normalized * maxAccel;
    }

    print(body.velocity + " ==> " + deltaV + " ==> " + accel);
    body.AddRelativeForce(accel);
}

public void Move(float vR, float vL)
{
    /* ... */

    /**
     * R = wheel radius
     * L = distance between wheels
     * phi = rotation angle (which way the robot is facing)
     *     = R/L (v_r - v_l)
     * dx = R/2 (v_r + v_l) cos(phi)
     * dy = R/2 (v_r + v_l) sin(phi)
     * https://www.coursera.org/learn/mobile-robot/lecture/GnbnD/differential-drive-robots
     */

    phi = R / L * (vR - vL);
    float dX = R / 2 * (vR + vL) * Mathf.Cos(phi);
    float dY = R / 2 * (vR + vL) * Mathf.Sin(phi);

    /* ... */

    /* move forward */
    acceleration = new Vector3(dY, 0, dX);
    print(acceleration);

}

[1] Sorry for the german legend, translation follows: “Im Uhrzeigersinn” = clockwise, “Gegen …” = CCW, “Vorwaerts” = forward, “Ruckwaerts” = backwards


Get this bounty!!!

#StackBounty: #unity #dll #force-feedback How to get a good Force Feedback .dll Feedback for Steering Wheels? || How to access Force Fe…

Bounty: 100

I want to implement a steering wheel with Force Feedback to my game and I encountered this problem:
I couldnt do it with performance.
I have found a .dll for that online, but it had issues like:

  1. It was not performant
  2. It made my steering wheel react too delayed

Otherwise I was not able to access the steering wheel.
Is it even possible to make a performant steering wheel and force feedback game with good performance?
How else can I access force feedback ?


Get this bounty!!!

#StackBounty: #unity #nautilus #gtk Ubuntu 16.04 broken menus for some apps always displayed

Bounty: 50

Running 16.04 & Unity on a new Dell XPS13 laptop, freshly installed.
The menus for some apps (terminal, nautilus) are always shown below the app title bar.
Some other apps like Chrome or Text editor/gedit do show correctly at the top bar as it is supposed to considering the use of global menus.

This is weird as it does not happen for both userids configured on this machine. The other user desktop shows menu for all apps at the top bar using global menus correctly.

See pic. And nevermind the Macbuntu theme, I just installed it to test with it, but the same behavior was experienced before I did it.

Any help?

Screenshot


Get this bounty!!!

#StackBounty: #unity #shaders #graphics #fragment-shader #cg Depth Intersection Shader

Bounty: 50

I am trying to create a shader in Unity that shows where intersections occur between objects.

Most of the shader I have so far is based off of this youtube tutorial. However, I have made some slight modifications to it. The main one being that it is only using a camera’s depth texture instead of the depthnormal texture.

Shader "Intersection/Unlit"
{
    Properties
    {
        _Color("Color", Color) = (0,0,0,0)
        _GlowColor("Glow Color", Color) = (1, 1, 1, 1)
        _FadeLength("Fade Length", Range(0, 2)) = 0.15
    }
    SubShader
    {
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite On

        Tags
        {
            "RenderType" = "Transparent"
            "Queue" = "Transparent"
        }

        Pass
        {
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float2 screenuv : TEXCOORD1;
                float4 vertex : SV_POSITION;
                float depth : DEPTH;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

                o.screenuv = ((o.vertex.xy / o.vertex.w) + 1) / 2;
                o.screenuv.y = 1 - o.screenuv.y;
                o.depth = -UnityObjectToViewPos(v.vertex).z *_ProjectionParams.w;

                return o;
            }

            sampler2D _CameraDepthTexture;
            fixed4 _Color;
            fixed3 _GlowColor;
            float _FadeLength;

            fixed4 frag (v2f i) : SV_Target
            {
                float screenDepth = Linear01Depth(tex2D(_CameraDepthTexture, i.screenuv));
                float diff = screenDepth - i.depth;
                float intersect = 0;

                if(diff > 0)
                    intersect = 1 - smoothstep(0, _ProjectionParams.w * _FadeLength, diff);

                fixed4 glowColor = fixed4(lerp(_Color.rgb, _GlowColor, pow(intersect, 4)), 1);

                fixed4 col = _Color * _Color.a + glowColor;
                col.a = _Color.a;
                return col;
            }
            ENDCG
        }
    }
}

This shader produces a result that looks like this.

enter image description here

However, this is a problem as there are large areas of the object that remain the initial blue colour. What I was expecting was something that looked like this.

enter image description here

I think the issue is caused when calculating screen depth from i.screenuv

float screenDepth = Linear01Depth(tex2D(_CameraDepthTexture, i.screenuv));

I have tried removing the difference check, this initially appeared to work. Although, when I placed an object in front of the object with this shader, the shader behaved as if there was a collision when there was not. As you can see below.

enter image description here

I would appreciate any help in resolving the issue


Get this bounty!!!