Using ChatGPT for code to help program a camera controller for a new location comprised of only one ultra-wide image.
Read the rest of the city hall series: part 1, part 2, part 3, part 4.
Eventually this room will be full of people waiting in line to meet the city administrator AI. Each person will have a medium sized quest for you to solve before you can advance in the game. You can solve these quest in any order you like.
Location image generation
This location image was created using a combination of Midjourney pan, zoom and vary region tools and photoshop kit-bashing and generative fill. It was pretty involved, as it has multiple different spaces that needed to all match together.
3D modeling the location
As this is not a single image, but a composite of multiple images, the perspective might be way off at the image edges. But in this case fSpy gave me a pretty decent result. I did have to make a few tries as with one vanishing point (camera in a perfect 90 degree angle).
This required me to model a few versions of the basic room shape and bring them over to Unity and see which room depth felt the best. Tweaking the lens focal length made the space deeper / shallower. I ended up with 22mm which was a good compromise between distortions and room depth.
When modeling the scene in blender, I did have to be a little more accurate than in most of the scenes, as this scene would have a “free moving” camera.
Parallax
As I was working with simple camera projections, I did not want to do any UV unwrapping, this is why I ended up adding a secondary material for the areas that had occlusion. This would allow me to have pieces of the painting slide on top of other pieces of the painting.
Next, I needed to make a second version of the image where I paint out all the occluding objects.
The difference is subtle. I did not need to do a super good job with this one. I only needed to provide enough data to be able to remove the waiting room chair legs, ends of the sitting areas, some boxes on the floor, the left side of the Photo Booth, and expose the corridor on the right. Simple stuff. This was easy to test so I just kept going between Unity and Photoshop to see that everything was working as expected.
I also created a mask for the reflection on the floor, which I painted out from the original image with photoshop. It is a combination of filters, hand painting and photo overlays. The goal was to create a spotty reflection with a lot of variance.
This mask is then used in the planar reflection material. to add reflections to the floor.
I am a big fan of these reflections on the floors. And I like to use them in as many scenes as possible.
Using ChatGPT for code: camera motion
After the mesh is imported to Unity and all the lighting and hotspots set up, it was time to start to work on the camera.
My plan was to create a script that makes the camera follow the character sideways as he moves in the space (trucking). I also wanted the camera to turn left to right (pan) as the character moves to the edges of the space so that I can get some help from the overlap as the perspective does not need to shift quite as much.
As an afterthought, I also ended up doing a “dead space” at the middle of the camera range to make the space feel more like 3 rooms stitched together. The reasoning was to make the game focus on these 3 spaces individually so the player would have less things to focus on at once.
I started as I always do. Writing the code by hand. But I could not remember off the bat how to correctly turn the camera from left to right. What transform parameter to use. So I immediately thought to google it, but then I remembered chatGPT and how much people have used it, successfully, to write code. I figured it was finally time to try it!
Me
I need a C# script for unity, can you help?
Certainly! I’d be happy to help you with a C# script for Unity. Could you please provide more details about what you’re trying to achieve? Knowing the specific functionality or feature you’re working on will help me tailor the script to your needs.
Me
ok, so I have a camera that is oriented in space. I want to turn this camera left and right with a float slider. can you provide me with. script for that
Certainly! If you want to rotate a camera left and right based on a float slider input, you can use the following script. This script assumes you have a camera attached to the GameObject and a UI Slider for input.
CameraRotation
using UnityEngine;
using UnityEngine.UI;
public class CameraRotation : MonoBehaviour
{
public Camera mainCamera;
public Slider rotationSlider;
public float rotationSpeed = 5f;
void Start()
{
if (mainCamera == null)
{
// Assuming the script is attached to the same GameObject as the camera
mainCamera = GetComponent<Camera>();
}
if (rotationSlider == null)
{
// Replace "Slider" with the actual name of your Slider GameObject
rotationSlider = GameObject.Find("Slider").GetComponent<Slider>();
}
// Set the initial value of the slider to the current rotation
rotationSlider.value = mainCamera.transform.eulerAngles.y;
}
void Update()
{
// Get the rotation value from the slider
float rotationValue = rotationSlider.value;
// Update the camera rotation based on the slider value
RotateCamera(rotationValue);
}
void RotateCamera(float rotationValue)
{
// Rotate the camera around the Y-axis
mainCamera.transform.eulerAngles = new Vector3(
mainCamera.transform.eulerAngles.x,
rotationValue,
mainCamera.transform.eulerAngles.z
);
}
}
This script assumes that you have a camera (mainCamera
), a Slider (rotationSlider
), and a public variable rotationSpeed
that controls the rotation speed. Attach this script to a GameObject in your scene, and assign the camera and slider references in the Unity Editor.
Make sure to set up the Slider’s min and max values according to your needs. You can tweak the rotationSpeed
to control how fast the camera rotates in response to the slider input.
I am nos sure if the code the thing wrote works or not, but it had the important bit:
// Rotate the camera around the Y-axis
mainCamera.transform.eulerAngles = new Vector3(
mainCamera.transform.eulerAngles.x,
rotationValue,
mainCamera.transform.eulerAngles.z
);
This is pretty much how I always code. I have an idea what I need done, then I google how other people did it, find a thing that is at the core (like this rotate around y-axis bit) and then write the rest around it myself. Until I hit a snatch and then google for more.
With this y-axis thing I managed to make the full code for the camera to follow the character. I added min and max values for position and rotation to clamp th values so the camera stays in check and I also added smooth follow to the script. And other neat stuff to be able to fully control the movement of the camera
I was very happy with the way the camera stays in the range I wanted to. The script did exactly what I wanted it to do. But soon I noticed that as the player needs to spend a lot of time moving in the middle waiting area, having the camera move massively is not ideal!
I needed to add a dead zone for the middle of the space. ChatGPT to the rescue!
Me
another one, can you show the c# for adding a dead zone of 5 around 0 for a float that can range from -100 to 100
Certainly! If you want to add a dead zone around 0 for a float that can range from -100 to 100, you can modify the input value to be 0 when it falls within a certain range. Here’s an example:
DeadZoneExample
using UnityEngine;
public class DeadZoneExample : MonoBehaviour
{
public float inputValue; // Assuming this is the input value you want to apply a dead zone to
public float deadZoneThreshold = 5f;
void Update()
{
// Get the raw input value (in the range of -100 to 100, for example)
float rawInputValue = /* Get your raw input value here */;
// Apply the dead zone
inputValue = ApplyDeadZone(rawInputValue, deadZoneThreshold);
// Use the modified input value for your logic
// For example, rotate an object based on the modified input value
RotateObject();
}
float ApplyDeadZone(float input, float threshold)
{
// If the input is within the dead zone range, set it to 0
if (Mathf.Abs(input) < threshold)
{
return 0f;
}
// Otherwise, return the original input
return input;
}
void RotateObject()
{
// Replace this with your actual logic using the modified input value
transform.Rotate(Vector3.up, inputValue * Time.deltaTime);
}
}
n this example, the ApplyDeadZone
function checks if the absolute value of the input is less than the dead zone threshold. If it is, it sets the input to 0; otherwise, it returns the original input. This way, when the input is close to 0 within the dead zone range, the modified input is effectively 0.
Adjust the deadZoneThreshold
variable according to your needs. This script assumes you have a variable inputValue
that you want to modify, and it includes a placeholder function RotateObject
to demonstrate using the modified input for some object rotation. Replace /* Get your raw input value here */
with the actual code to get your raw input value.
Again, I simply copied the part that I needed from the code:
float ApplyDeadZone(float input, float threshold)
{
// If the input is within the dead zone range, set it to 0
if (Mathf.Abs(input) < threshold)
{
return 0f;
}
// Otherwise, return the original input
return input;
}
Both of these use cases were embarrassingly simple, but I started to use chatGPT instead of Unity manual or googling for help. Even if my requirements were simple, it was faster to use chatGPT than any other method to refresh my memory.
The dead zone worked beautifully. Making the room move in sections and making the scene a lot easier to digest. I think. While still making it feel very 3D. As a scene, this actually is fully 3D, not 2.5D at all.
I had not used chatGPT like this before. I know I should have! Everyone else had! But this will fundamentally change the way I write code in the future.
Leave a Reply