Needle.Tools Source Code Request

Hey @marcel :cactus: and Needle Team!

I hope this message finds you well. I must say, I’m quite impressed with its performance and functionality, especially the scrolling setup. It’s evident that a lot of thought and effort went into creating this tool, and I commend you for that.

I’ve had the opportunity to experiment with some of the Unity Samples to enhance my skills. Currently, I’m working on developing a 3rd person controller extension specifically designed for gamepad API support.

I’ve been researching different approaches to improve the user experience, and I believe that examining the scrolling setup of http://needle.tools could provide valuable insights and inspiration for my own project. I wanted to kindly ask if it would be possible for you to share the source code of landing page, unity project file, and how you implemented the scroll/camera movement in a React environment. In addition to preloading the models so that they are ready to be loaded to canvas when the next section is ready.’

Thanks in advance!

Original Post on Discord

by user 1107828510023753769

Hi, thank you for your kind words.

As a brief reply for now to maybe get you started / give you some more info here are two things you can look at immediately:

  • we have a builtin component called SceneSwitcher that has all you need (with some improvements over the one in the website) to load/unload/preload sections

  • our samples have a scrollytelling example as well as a “product flyover” example which are both no code but could be a good starting point if you want to control the scene with a timeline and then switch to another section. In the website we use timeline to animate the camera position and look at target along a spline.

This is exactly the breakdown I was looking for, thank you. I am experimenting with the Blender addon and have successfully exported a custom scene to GLB.

I had originally animated a 3D Portfolio with React Three Fiber and Framer Motion along with a Mixamo avatar.

I am now trying to port these elements over to Needle/Unity to see if I can create a storytelling user experience, along with an avatar that uses a modified version the 3rd Person Controller sample

by user 1107828510023753769

by user 1107828510023753769

Cool happy to help. Let us know if you have any more questions.
Do you have a link to your original project made with r3f?

Yeah here is a link to the repo, still a WIP:

It’s based off of the Wawa Sensei tutorial
(link to tutorial demo: https://r3f-portfolio-responsive.vercel.app )

by user 1107828510023753769

I was able to map out to map out the camera movement I want to accomplish in Needle using TheatreJS:
CameraMovement_TheatreJS.mp4

by user 1107828510023753769

I am going to compare the workflow for each technology and maybe make a blog post about it.

by user 1107828510023753769

Hi, looking good :slightly_smiling_face: so you want to use Blender to create this with Needle? Then you can just animate the camera and add the track to an nla track + add a PlayableDirector into your Blender scene on any object (could be a extra empty object or the camera object for example).

By default it will then just play and loop the nla tracks - for controlling it with scroll you can create a new script and add this code to the script file (for example)

import { Behaviour, PlayableDirector, serializable, Mathf } from "@needle-tools/engine";

export class ScrollTimeline extends Behaviour {

    @serializable(PlayableDirector)
    timeline?: PlayableDirector;

    @serializable()
    sensitivity: number = .5;

    @serializable()
    clamp: boolean = false;

    private _targetTime: number = 0;

    awake() {
        this.context.domElement.addEventListener("wheel", this.onWheel);
        if (this.timeline) this.timeline.pause();
    }

    private onWheel = (e: WheelEvent) => {
        if (this.timeline) {
            this._targetTime = this.timeline.time + e.deltaY * 0.01 * this.sensitivity;
            if (this.clamp) this._targetTime = Mathf.clamp(this._targetTime, 0, this.timeline.duration);
        }
    }

    update(): void {
        if (!this.timeline) return;
        const time = Mathf.lerp(this.timeline.time, this._targetTime, this.context.time.deltaTime / .3);
        this.timeline.time = time;
        this.timeline.pause();
        this.timeline.evaluate();
    }
}

image.png

Thank you so much for this breakdown! I will give it a try and post results in this thread.

by user 1107828510023753769

Hi @TheDigitalGriot let me know if there’s anything we can assist you with :slightly_smiling_face: