autonomnom / Water-on-Mars

meeeeeeow
0 stars 0 forks source link

Rewrite camera system, where to find the smooth? #6

Closed autonomnom closed 8 years ago

autonomnom commented 8 years ago

Structure for now is..

Detection of obstacles is managed through 3 methods: a) A checking ray from the camera to the follow/identity.

 bool augenKontakt() {

    GameObject ida = GameObject.Find(G.identitaet.ToString());
    float distance = Vector3.Distance(ida.transform.position, body.position);
    RaycastHit bam;

    kontakt = new Ray(body.position, -(body.position - ida.transform.position));

    if(Physics.Raycast(kontakt,out bam,distance,groundMask)) {

        return false;
    }
    else return true;
}

b) Multiple raycasts spherical arranged with the camera as its origin for obstacles around the camera

public Ray[] letTheRaysRain(int rayz) {

    Ray[] rayt = new Ray[rayz];

    for (int i = 0; i < rayt.Length; i++) {

        float abstand = Mathf.PI / rayz;
        float y = Mathf.Cos(i * abstand);
        float phi = i * ((10f * Mathf.PI) / rayz);
        float x = Mathf.Sin(i * abstand) * Mathf.Sin(phi);
        float z = Mathf.Sin(i * abstand) * Mathf.Cos(phi);
        rayt[i] = new Ray(_body.position, new Vector3(x, y, z));      
    }

    // for debug
    if (activateDebug) {

        for (int i = 0; i < rayt.Length; i++) {

            Debug.DrawRay(rayt[i].origin, rayt[i].direction);
        }
    }

    return rayt;
}

public bool checkForCollisionNearBy(Ray[] allrayz, LayerMask layerMask, float castRange) {

    for (int i = 0; i < allrayz.Length; i++) {

        RaycastHit piu;
        if (Physics.Raycast(allrayz[i], out piu, castRange, layerMask)) {

            return true;
        }
    }

    return false;
}

c) An additional raycast backwards while the camera is zooming/moving to the identity to prevent jittering.

    // special case when no spherical detection is positive but would be when zooming out
    if (status != Polizei.fern) {

        Ray rueckwarts = new Ray(body.position, body.position - foollow.position);
        if (Physics.SphereCast(rueckwarts, blickdistanz * 2, 10, groundMask)) {

            zoom = true;
        }
    }

//

To get smooth camera movements while zooming in and out i have a method containing pretty mechanical if/else scenarios:

void cameraOrientation() {

    // no eye contact to the identity
    if (!augenKontakt() || zoom) {

        // if the camera is at max distance to the identity
        if (status == Polizei.fern) {

            statDelay = 0;
            status = Polizei.reisendzu;
        }
        // if it is already traveling
        else if (status == Polizei.reisendzu) {

            // to the target
            if (camDistance != camDistanceZoom && camUp != camUpZoom) {

                camDistance = Mathf.SmoothDamp(camDistance, camDistanceZoom, ref lerpBeschleunigung, Time.fixedDeltaTime / lerpZeit); ;
                camUp = Mathf.SmoothDamp(camUp, camUpZoom, ref lerpBeschleunigung, Time.fixedDeltaTime / lerpZeit);
                statDelay = 0;
            }
            else { status = Polizei.nah; statDelay = 0; }
        }
        // away from it
        else if (status == Polizei.reisendweg) {

            status = Polizei.reisendzu;
            statDelay = 0;
        }
    }
    else if (augenKontakt() || !zoom) {

        // delay while camera is close, after the delay camera is drving back
        if (status == Polizei.nah) {

            if (!zoom) {

                if (statDelay < statDelayMax) { statDelay += Time.fixedDeltaTime; }
                else { statDelay = 0; status = Polizei.reisendweg; }
            }
            else statDelay = 0;

        }
        // if camera is in move while the identity is seen
        else if (status == Polizei.reisendzu) {

            // towards the target although now there is eye contact
            if (statDelay < statDelayMax) { statDelay += Time.fixedDeltaTime; }
            else { statDelay = 0; status = Polizei.reisendweg; }
        }
        // away to the original camera position
        else if(status == Polizei.reisendweg) {

            if (camDistance != _camDistance && camUp != _camUp) {

                camDistance = Mathf.SmoothDamp(camDistance, _camDistance, ref lerpBeschleunigung, Time.fixedDeltaTime / lerpZeit);
                camUp = Mathf.SmoothDamp(camUp, _camUp, ref lerpBeschleunigung, Time.fixedDeltaTime / lerpZeit);
            } 
            else {

                statDelay = 0;
                status = Polizei.fern;
             }
        }
    }
}

// It somehow works but doesn't feel right yet, it feels mechanical as well. I'm missing intelligent movement without even the slightest jittering. Ideas: a) Taking the distance and directions out of the raycasthit info, and adding them to the targetposition variable used to apply the changes. b) Cast more specific, environment-friendly, not clever spherical generated. This might make sense in this game, to a certain degree, but doesn't feel right as well. In the end it feels even more mechanical (i guess). c) Remove the rigibody and let the camera float through the body/environment. Might be irritating, atmosphere-breaking, but also interesting? There could be pictures and objects placed within the body, only to be found with the character/camera movement. Not easter-eggish, more like story-adding. Not sure how much this would collide with the story/gamedesign concept. d) Going deeper into the already-existing code and make it even finer. Maybe this will feel less mechanical or superior-mechanical like a crazy steampunkish vehicle. In case i stop dreaming of an a glowing liquid, warpspeed, magical solution..

autonomnom commented 8 years ago

a) didn't work but on the road i found some issues that might have added problems to it while testing this option b) this is problably the option i went for. kind of a fusion between b) and d) c) decided against to push the idea of a body that's more than a hollow d) see b)