- Home /
LineRenderer with moving camera
Still in progress of my game. I'm faced with a problem. The game that I'm working on is similar to Cave Run. The player is constantly running and the camera moves with the player (correct me if this should not be the case). For my game, as the player is running, they are able to draw on the screen to activate skills. I've attached the script of the LineRenderer to the camera, and when I draw, the first point of the line renderer moves out of view from the iPhone as the camera is still moving.
What I want to achieve is to have the drawing symbol remain on screen like how GUI does. A solution that I have is to move the platform instead. But this might cause some problems when adding obstacles into the stage.
EDIT: Here's my codes
class Stroke extends MonoBehaviour { public var currentCamera : Camera; private var player : Transform; private var distance = 1; private var drawArray : ArrayList = new ArrayList(); private var lineMat : Material;
function Stroke()
{
}
function Awake()
{
currentCamera = Camera.main;
player = GameObject.FindWithTag("Player").transform;
}
function Update()
{
ProcessInput();
var strokeRenderer : LineRenderer = GetComponent(LineRenderer);
strokeRenderer.SetVertexCount(drawArray.Count);
strokeRenderer.SetColors(Color(0,0,1,1), Color(0,0,1,0));
strokeRenderer.material = new Material (Shader.Find("Particles/Additive"));
strokeRenderer.SetWidth(0.1,0.1);
for (var i : int = 0; i < drawArray.Count; i++)
{
strokeRenderer.SetPosition(i, drawArray[i]);
}
}
function ProcessInput()
{
for(var p : int = 0; p < Input.touchCount; p++)
{
var touchPoint : Vector3 = Input.GetTouch(p).position;
var screenPoint : Vector3 = new Vector3(touchPoint.x, touchPoint.y, distance);
var worldPoint : Vector3 = currentCamera.ScreenToWorldPoint(screenPoint);
if(Input.touchCount == 1)
{
if(Input.GetTouch(p).phase == TouchPhase.Began)
{
drawArray.Add(worldPoint);
}
if(Input.GetTouch(p).phase == TouchPhase.Moved)
{
drawArray.Add(worldPoint);
MovePlayer();
}
if(Input.GetTouch(p).phase == TouchPhase.Ended)
{
drawArray.Clear();
}
}
}
}
function MovePlayer()
{
var startPos : Vector3 = drawArray[0];
var endPos : Vector3 = drawArray[drawArray.Count -1];
direction = (endPos - startPos).normalized;
player.transform.position.x += direction.x * 0.4;
}
}
Answer by Herman-Tulleken · Nov 12, 2010 at 07:19 AM
You simply have to update the points in Update to new world positions each update (and not just when you create the curve).
Something along:
int i = 0;
foreach screenPosition of my curve Vector3 worldPosition = camera.ScreenToWorldPoint(screenPosition);
lineRenderer.SetPosition(i, worldPosition); i++;
The tricky part will be to update if you interpolate screenpositions (or worldPositions), or sample them. In either case, the slow but easy method will be to re-interpolate and resample each Update.
Once you have got this going, you can optimise by storing the the right number of points in screen space. Then you only have to convert to world space - no need to resample or reinterpolate.
Edit: Here is how it looks in your code:
class Stroke extends MonoBehaviour { public var currentCamera : Camera; private var player : Transform; private var distance = 1; private var drawArray : ArrayList = new ArrayList(); private var lineMat : Material;
//...
function Update()
{
ProcessInput();
var strokeRenderer : LineRenderer = GetComponent(LineRenderer);
strokeRenderer.SetVertexCount(drawArray.Count);
strokeRenderer.SetColors(Color(0,0,1,1), Color(0,0,1,0));
strokeRenderer.material = new Material (Shader.Find("Particles/Additive"));
strokeRenderer.SetWidth(0.1,0.1);
for (var i : int = 0; i < drawArray.Count; i++)
{
//Do the conversion here:
var worldPoint : Vector3 = currentCamera.ScreenToWorldPoint( drawArray[i]);
strokeRenderer.SetPosition(i, worldPoint);
}
}
function ProcessInput()
{
for(var p : int = 0; p < Input.touchCount; p++)
{
var touchPoint : Vector3 = Input.GetTouch(p).position;
var screenPoint : Vector3 = new Vector3(touchPoint.x, touchPoint.y, distance);
if(Input.touchCount == 1)
{
if(Input.GetTouch(p).phase == TouchPhase.Began)
{
//Add screen points here
drawArray.Add(screenPoint );
}
if(Input.GetTouch(p).phase == TouchPhase.Moved)
{
//Add screen points here
drawArray.Add(screenPoint );
MovePlayer();
}
if(Input.GetTouch(p).phase == TouchPhase.Ended)
{
drawArray.Clear();
}
}
}
}
function MovePlayer()
{
var startPos : Vector3 = drawArray[0];
var endPos : Vector3 = drawArray[drawArray.Count -1];
direction = (endPos - startPos).normalized;
player.transform.position.x += direction.x * 0.4;
}
}
I understand the logic, but i'm a little stuck at how i should put it in.
@Robindoo I adapted your code to implement the scheme.
Thanks once again. So far the controls seem to be working fine. Only when put together with some of my friends file it experience some lag. Haha. But in the mean time we are still working to fix things out.